Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
Юн
0 / 0 / 0
Регистрация: 11.01.2014
Сообщений: 39
#1

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

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

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

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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.01.2015, 22:45
Ответы с готовыми решениями:

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

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

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

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

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

20
hoggy
Заблокирован
Эксперт С++
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
S_el
2137 / 1667 / 353
Регистрация: 15.12.2013
Сообщений: 6,623
02.01.2015, 23:42 #4
Цитата Сообщение от Юн Посмотреть сообщение
Когда добавляю в вашу программу перед закрывающей скобкой cin.get(); компилятор фиксирует её как ошибку. Не пойму, что с этим делать.
Сравните верхнюю часть своего и приведенного кода.
Или возьмите тот-же cout.
0
hoggy
Заблокирован
Эксперт С++
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
S_el
2137 / 1667 / 353
Регистрация: 15.12.2013
Сообщений: 6,623
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
hoggy
Заблокирован
Эксперт С++
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
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,304
Записей в блоге: 5
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
SlavaSSU
217 / 162 / 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
BRcr
4015 / 2305 / 291
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 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
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,304
Записей в блоге: 5
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
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,304
Записей в блоге: 5
03.01.2015, 18:41 #16
Цитата Сообщение от Юн Посмотреть сообщение
Всех с наступившим!
0
BRcr
4015 / 2305 / 291
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 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
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,304
Записей в блоге: 5
03.01.2015, 19:31 #19
Цитата Сообщение от BRcr Посмотреть сообщение
есть только сдвиг элементов последовательности
То есть в целом всё зависит от соотношения размера строки и размера алфавита? Подозреваю, что для некитайского алфавита и достаточно большой строки работать с оригиналом, всё же невыгодно.
Цитата Сообщение от BRcr Посмотреть сообщение
С праздничком!
0
BRcr
4015 / 2305 / 291
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
03.01.2015, 22:48 #20
Цитата Сообщение от Юн Посмотреть сообщение
как определить элементы массива расположенные параллельно главной диагонали? Плиз *-*
Всего лишь сдвигом счетчика строк или колонок. К примеру, если главная диагональ задается синхронным инкрементом счетчиков, инициализированных нулями, то вторичная диагональ, расположенная над главной, задается синхронным инкрементом колонок, начиная с единицы, и строк, начиная с нуля.
0
03.01.2015, 22:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.01.2015, 22:48

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

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

Удалить из массива все одинаковые элементы, оставив их первые вхождения
Дан целочисленный массив размера N. Удалить из массива все одинаковые элементы,...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru