Удалить повторяющиеся символы из символьного массива с++
Стоит задача удалить повторяющиеся символы с массива символов. То есть , если имеем "aabbccdd" , должно получиться "abcd". Написал вот такой вот код , который показался мне абсолютно правильным но некоторые символы все равно повторяются дважды , а то и трижды. m- количество символов , temp - сам массив. Просьба не осуждать за наличие глупых ошибок (если таковы будут).
UPD:
Поскольку не совсем точно описал проблему , добавлю , что во всей строке символ может появляться однажды. То есть строка "abcdeabcdeabcde" на выходе будет "abcde". Спасибо всем кто откликнулся на мой вопрос!
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
if (i == j) continue;
if (temp[i] == temp[j]) {
for (int k = i; k < m; k++) {
temp[k] = temp[k + 1];
}
m--;
continue;
}
}
}
Ответы (3 шт):
Ну, я бы делал примерно так:
char s[] = "aabcccddegfhtttj";
for(char last = *s, *f = s, *l = s;;)
{
while(*l == last) l++;
last = *++f = *l;
if (*l == 0) { *f = 0; break; }
}
cout << s;
Используем map:
#include <iostream>
#include <map>
int main() {
char temp[] = "aabbccddeeaaaaaffffmmmmekkkk";
std::cout << temp << std::endl;
std::map<char,bool> m;
for(char *it = temp; *it != '\0'; ++it) {
m[*it] = true;
}
char* write = temp;
for(auto it: m) {
*write++ = it.first;
}
*write = '\0';
std::cout << temp << std::endl;
}
// aabbccddeeaaaaaffffmmmmekkkk
// abcdefkm
Варианты с заменой повторяющихся символов находящихся друг с другом:
С указателями:
#include <iostream>
int main() {
char temp[] = "aabbccddeeaaaaaffffmmmmekkkk";
std::cout << temp << std::endl;
char* write = temp;
for(char* read = temp + 1; *read != '\0'; ++read) {
if(*read != *write) *++write = *read;
}
*++write = '\0';
std::cout << temp << std::endl;
}
// aabbccddeeaaaaaffffmmmmekkkk
// abcdeafmek
или через индексы массива:
#include <iostream>
#include <cstring>
int main() {
char temp[] = "aabbccddeeaaaaaffffmmmmekkkk";
std::cout << temp << std::endl;
int m = strlen(temp);
int j = 0;
for(int i = 1; i < m; ++i) {
if(temp[i] != temp[j]) temp[++j] = temp[i];
}
temp[++j] = '\0';
std::cout << temp << std::endl;
}
// aabbccddeeaaaaaffffmmmmekkkk
// abcdeafmek
Если рассматривать только однобайтные кодировки и требуется оставить лишь первое вхождение символа, то можно вот так:
#include <stdio.h>
#include <stdlib.h>
int
main (int ac, char *av[])
{
char str[10240];
while (fgets(str, 10240, stdin)) {
int chars[256] = {0}; // множество встреченных символов, код символа это индекс в данном массиве
int n = 0; // количесво символов в массиве после удаления дубликатов
for (int i = 0; str[i]; i++) {
int chix = (unsigned char)str[i];
if (chars[chix] == 0)
str[n++] = str[i]; // такой символ встретился впервые
chars[chix]++;
}
str[n] = 0;
puts(str);
}
return puts("End") == EOF;
}