0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
1

Удалить из слова все повторяющиеся буквы, оставив их первые вхождения

02.01.2015, 22:45. Показов 4440. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Условие:Дано слово. Удалить из него все повторяющиеся буквы, оставив их первые вхождения: в слове должны остаться только различные буквы.
Разработать алгоритм и программу решения задачи. Разработать пользовательский интерфейс для программы.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
using namespace std;
int main()
{
      char OneStr[]="aaaniiimeee";
      char TwoStr[10];
       char * bp = TwoStr;
      cout<<"before:"<<OneStr<<endl;
      int col=strlen(OneStr);
      int i,j; 
      for (i=0; i<col; i++) {
      if (OneStr[i]==OneStr[i+1])     
      *bp=OneStr[i];
      }
      cout<<"after:"<<TwoStr;
  cin.get();
  cin.get();
  
      }
Прога пашет, но в результате выводит только последнюю бувку е. Почему?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.01.2015, 22:45
Ответы с готовыми решениями:

Удалить из строки все повторяющиеся буквы, оставив только их первые вхождения
2.Даны строки, содержащие латинские буквы. Удалить из строки все повторяю* щиеся буквы, оставив...

Удалить из очереди все повторяющиеся слова, оставив только их первые вхождения
Создать очередь, содержащую слова. Удалить из очереди все повторяющиеся слова, оставив только их...

Создать очередь, содержащую слова. Удалить из очереди все повторяющиеся слова, оставив только их первые вхождения
#include &lt;iostream&gt; using namespace std; struct queue { int inf; queue *next; }; void...

Дано слово. Удалить из него все повторяющиеся буквы, оставив их первые вхождения, то есть в слове должны остаться только различные буквы.
Дано слово. Удалить из него все повторяющиеся буквы, оставив их первые вхождения, то есть в слове...

20
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2015, 23:27 2
http://rextester.com/VUW69165

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <algorithm>
#include <iostream>
#include <string>
 
 
void remove_duplicates(std::string& src)
{
    std::string work = src;
    
    std::sort(work.begin(), work.end() );
   
    work.erase( 
        std::unique(work.begin(), work.end() ), 
        work.end()
    );
    
    for(size_t n=0; n<src.size() ; )
    {
        const size_t it = work.find( src[n] );
        if(it==std::string::npos)
            src.erase(n,1);
        else
            work.erase(it,1),
            ++n;
    }
}
 
int main()
{
    std::cout << "Hello, world!\n";
    
    std::string value = "122234444322111000444";
    std::cout<< "before: "<< value <<'\n';
    
    remove_duplicates(value);
    
    std::cout<< "after: "<< value <<'\n';
        
        
}
1
0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
02.01.2015, 23:38  [ТС] 3
hoggy, Вы удалили повторяющиеся элементы, тем самым получили нужный результат. В принципе, так по условию правильнее, но если как я, перезаписать первые вхождения в новый массив? Почему всё таки в результате у меня лишь последнюю букву показывает?
И ещё одно. Когда добавляю в вашу программу перед закрывающей скобкой cin.get(); компилятор фиксирует её как ошибку. Не пойму, что с этим делать..
0
2442 / 1840 / 406
Регистрация: 15.12.2013
Сообщений: 8,236
02.01.2015, 23:42 4
Цитата Сообщение от Юн Посмотреть сообщение
Когда добавляю в вашу программу перед закрывающей скобкой cin.get(); компилятор фиксирует её как ошибку. Не пойму, что с этим делать.
Сравните верхнюю часть своего и приведенного кода.
Или возьмите тот-же cout.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2015, 23:46 5
Цитата Сообщение от Юн Посмотреть сообщение
Почему всё таки в результате у меня лишь последнюю букву показывает?
Потому что:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
using namespace std;
int main()
{
  
    char OneStr[]="aaaniiimeee";
  
    char TwoStr[10];
   
    char* bp = TwoStr;  //<---- смотрит на начало массива
  
    cout<<"before:"<<OneStr<<endl;
  
    int col=strlen(OneStr);
  
    int i,j; 
    for (i=0; i<col; i++) 
        if (OneStr[i]==OneStr[i+1])     
            *bp=OneStr[i];            //<---- всегда меняем только первый символ
 
    cout<<"after:"<<TwoStr; //<---- покажет только 1 символ
  
}
Добавлено через 2 минуты
Цитата Сообщение от Юн Посмотреть сообщение
но если как я, перезаписать первые вхождения в новый массив?
ваш алгоритм не соответствует задаче:

http://rextester.com/BIL8304
0
0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
02.01.2015, 23:54  [ТС] 6
S_el, ничего схожего в наших кодах. Даже немного смешно. Ну ведь вообще не по условию я сделала и то не верно. Показывает только 1 символ.

hoggy, голова болит позже лучше подумаю над этим, ото не прет..А вам спасибо.
0
2442 / 1840 / 406
Регистрация: 15.12.2013
Сообщений: 8,236
02.01.2015, 23:57 7
Цитата Сообщение от Юн Посмотреть сообщение
ничего схожего в наших кодах.
У вас cout,у hoggy - std::cout.
У вас cin, в аналогичном коде что должно быть?
0
0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
03.01.2015, 00:01  [ТС] 8
S_el, скорее всего std::cin
Но я так думаю, что он везде писал std:: потому-что заранее под заголовочными файлами не написал using namespace std;
Не так?
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.01.2015, 00:07 9
http://rextester.com/YVKOSG6659

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cstring>
using namespace std;
 
 
int main()
{
    const char first[]="annniiimmeee";
    cout<<"before:" << first << endl;
  
    char second[10] = {0};
    char* p = second;  
  
    size_t len = strlen(first);
  
    for (size_t i = 0; i < len; ++i) 
    {
        *(p++) = first[i];
        
        for (size_t n = i; n < len && first[n]==first[n+1]; ++n) 
            i=n+1;
    }
 
    cout<<"after:"<<second; 
  
}
Данный алгоритм отражает ваше решение из нуль-поста, но так же не соответствует задаче.

Потому что, если исходная строка будет:
C++
1
const char first[]="annniiimmeeeaaa";
то результат получится:
animea
Повторение букв 'a'.
Которых не должно быть по условию задачи.
0
0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
03.01.2015, 00:15  [ТС] 10
hoggy, хм, как видно, одни и те же у меня ошибки. Я бы со строками пока вообще не связывалась. Единственное задачи эти =-= Ну ничего, всему свое время. То что алгоритм не соответствует знаю. Вам спасибо большое)

S_el, сейчас снова посмотрела на код и поняла почему cin.get(); был не верным. Благодарю за подсказку. И не догадывалась))
0
Комп_Оратор)
Эксперт по математике/физике
8945 / 4699 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.01.2015, 01:23 11
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//если без STL, то логично создать пустой объект-контейнер (строка в данном случае)
//и добавлять в него очередной символ из строки-источника если его там ещё нет
//это гарантирует, что символ будет добавлен только один раз
 
#include <iostream>
#include <string>
using namespace std;
//принимает указатель на с-строку где ищем и символ который ищем
//возвращаем позицию где нашли или -1 если не нашли
int find_char(const char *src, char toFind){
for(int i=0; src[i]; ++i) if(src[i] == toFind) return i;
return -1;
}
 
int main()
{
char sourceStr[] = "aaaaaaannimmmmeeeanimeameniimena";
cout << "sourceStr= " << sourceStr << endl;
string containStr="";
containStr+=sourceStr[0];//в пустой контейнер можно смело добавить одну штуку
for (int i=1; sourceStr[i]; i++){
if( find_char(containStr.c_str(), sourceStr[i]) == -1 )//если не нашли
{       
containStr += sourceStr[i];//добавляем
}
cout<<containStr<<endl;//печатаем чтобы полюбоваться
}
system("pause");
    return 0;
}
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
03.01.2015, 01:34 12
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>;
 
using namespace std;
 
int cnt[256];
 
int main() {
    string s;
    cin >> s;
    int n = s.size();
 
    string ans;
    for(int i = 0; i < n; i++)
    {
        cnt[s[i]]++;
        if(cnt[s[i]] == 1)
            ans += s[i];
    }
 
    cout << ans << endl;
 
    return 0;
}
1
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
03.01.2015, 13:18 13
А если выкинуть все лишние сущности и представить, как ту же задачу выполнял бы человек своими глазками и ручками, получаем самый простой и естественный вариант:
C++
1
2
3
4
5
6
7
8
9
10
11
12
    using namespace std;
    //////////////////////////////////////
    string word( "annniiimmeeeaa" ), result;
 
    for ( int i( 0 ), i_limit( word.size( ) ); i < i_limit; ++i )
    {
        if ( word.find( word[ i ] ) == i )
        {
            result += word[ i ];
        }
    }
    cout << result;
Добавлено через 14 минут
Ан нет, сглупил. Вот так будет без лишних сущностей:
C++
1
2
3
4
5
6
7
8
9
10
11
12
    using namespace std;
    //////////////////////////////////////
    string word( "annniiimmeeeaa" );
 
    for ( int i( word.size( ) - 1 ); i >= 0; --i )
    {
        if ( word.find( word[ i ] ) != i )
        {
            word.erase( word.begin( ) + i );
        }
    }
    cout << word;
1
Комп_Оратор)
Эксперт по математике/физике
8945 / 4699 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.01.2015, 17:54 14
Цитата Сообщение от BRcr Посмотреть сообщение
Вот так будет без лишних сущностей:
При каждом word.erase(...) происходит же жесткая работа с памятью и объектом word? Не лучше ли создать новый объект и добавить туда всё что нужно. В крайнем случае в итоге с ним можно связать имя word. В конце концов ведь от исходного word в результирующем ничего почти и не остаётся, даже в том смысле, что оставшиеся слова в памяти расположены по большей части не там, где они были вначале. Да и это всё не важно по сравнению с тем, понятно это для Юн или нет. А она задумалась.
С наступившим!
1
0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
03.01.2015, 18:05  [ТС] 15
IGPIGP, спасибо, вот это довольно понятный код для того кто не работал со строками) оочень даже.
Главное задачки будут готовы, а потом смогу спокойно без спешки изучать и практиковаться в с++.)
BRcr, во дела. спасибо за труд))

Ах, ну да, ну да. Всех с наступившим!
0
Комп_Оратор)
Эксперт по математике/физике
8945 / 4699 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.01.2015, 18:41 16
Цитата Сообщение от Юн Посмотреть сообщение
Всех с наступившим!
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
03.01.2015, 19:13 17
Цитата Сообщение от IGPIGP Посмотреть сообщение
При каждом word.erase(...) происходит же жесткая работа с памятью и объектом word?
Да нет, в общем-то. Перераспределения памяти не происходит, есть только сдвиг элементов последовательности, то бишь серия swap'ов от конца. При формировании новой строки сдвига нет, но периодическое перераспределение памяти при увеличении количества элементов в контейнере есть. Точно не скажу без проверки, но примерно одно и то же...
Цитата Сообщение от Юн Посмотреть сообщение
BRcr, во дела. спасибо за труд))
Пожалуйста. Только никакой это был и не труд... просто ждал загрузки кой-чего.)

С праздничком!
1
0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
03.01.2015, 19:31  [ТС] 18
BRcr, больше практики и тогда и для меня это будет не труд. Всё впереди!)
Как в одном аниме: Бухать-Бухать-Бухать-Бухать-Бухать жалко, что у меня на новый год ниче кроме водки не было, а водку не пью ) эх, печаль

Добавлено через 3 минуты
BRcr, не подскажете, а как определить элементы массива расположенные параллельно главной диагонали? Плиз *-*
0
Комп_Оратор)
Эксперт по математике/физике
8945 / 4699 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.01.2015, 19:31 19
Цитата Сообщение от BRcr Посмотреть сообщение
есть только сдвиг элементов последовательности
То есть в целом всё зависит от соотношения размера строки и размера алфавита? Подозреваю, что для некитайского алфавита и достаточно большой строки работать с оригиналом, всё же невыгодно.
Цитата Сообщение от BRcr Посмотреть сообщение
С праздничком!
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
03.01.2015, 22:48 20
Цитата Сообщение от Юн Посмотреть сообщение
как определить элементы массива расположенные параллельно главной диагонали? Плиз *-*
Всего лишь сдвигом счетчика строк или колонок. К примеру, если главная диагональ задается синхронным инкрементом счетчиков, инициализированных нулями, то вторичная диагональ, расположенная над главной, задается синхронным инкрементом колонок, начиная с единицы, и строк, начиная с нуля.
0
03.01.2015, 22:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.01.2015, 22:48
Помогаю со студенческими работами здесь

Одномерные массивы, удалить все повторяющиеся элементы, оставив только первые вхождения
Задача на C++: из заданного массива удалить все повторяющиеся элементы, оставив только их первые...

Удалить из массива повторяющиеся элементы, оставив только их первые вхождения
Помогите, зачёт пишу

Удалить из массива повторяющиеся элементы, оставив только их первые вхождения
Как мне удалять повторяющийся элемент? #include &lt;iostream&gt; using namespace std; int main ()...

Удалить из массива повторяющиеся элементы, оставив только их первые вхождения (класс-контейнер вектор)
Добрый день!!! Не могли бы помочь написать программу на С++ при помощи класса-контейнера вектора....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru