Сортировка массива Char и удаление дубликатов
Я пытаюсь сделать некоторые манипуляции с массивами. Я делаю сортировку массивов символов и удаление дубликатов здесь. Ваши комментарии приветствуются. Хотя здесь не проводилось много испытаний и обработки ошибок.
#include<stdafx.h>
#include<stdlib.h>
#include<stdio.h>
#include<string>
using namespace std;
void sort(char *& arr)
{
char temp;
for(int i=0;i<strlen(arr);i++)
{
for(int j=i+1;j<strlen(arr);j++)
{
if(arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
bool ispresent(char *uniqueArr, char * arr)
{
bool isfound = false;
for(int i=0;i<strlen(arr);i++)
{
for(int j=0;j<=strlen(uniqueArr);j++)
{
if(arr[i]== uniqueArr[j])
{
isfound = true;
return isfound;
}
else
isfound = false;
}
}
return isfound;
}
char * removeduplicates(char *&arr)
{
char * uniqqueArr = strdup(""); // To make this char array modifiable
int index = 0;
bool dup = false;
while(*arr!=NULL)
{
dup = ispresent(uniqqueArr, arr);
if(dup == true)
{}//do nothing
else// copy the char to new char array.
{
uniqqueArr[index] = *arr;
index++;
}
arr++;
}
return uniqqueArr;
}
int main()
{
char *arr = strdup("saaangeetha");
// if strdup() is not used , access violation writing to
//location occurs at arr[i] = arr[j].
//This makes the constant string modifiable
sort(arr);
char * uniqueArr = removeduplicates(arr);
}
3 ответа
Если вы используете std::string
Ваш код (на самом деле это C-Style) может быть написан на C++ Style только в следующих строках:
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s= "saaangeetha";
std::sort(s.begin(), s.end());
std::string::iterator it = std::unique (s.begin(), s.end());
s.resize( it - s.begin());
std::cout << s ;
return 0;
}
Вывод: (все дубликаты удалены)
aeghnst
Демо: http://ideone.com/pHpPh
Если ты хочешь char*
в конце вы можете сделать это:
const char *uniqueChars = s.c_str(); //after removing the duplicates!
Если бы я делал это, я думаю, что сделал бы работу немного по-другому. Если вы можете позволить себе игнорировать мэйнфреймы IBM, я бы сделал что-то вроде этого:
unsigned long bitset = 0;
char *arr = "saaangeetha";
char *pos;
for (pos=arr; *pos; ++pos)
if (isalpha(*pos))
bitset |= 1 << (tolower(*pos)-'a');
Это связывает один бит в bitset
с каждой возможной буквой. Затем он проходит по строке и для каждой буквы в строке устанавливает соответствующий бит в bitset
, Чтобы распечатать буквы, как только вы закончите, вы должны пройти через набор битов и распечатать соответствующую букву, если этот бит был установлен.
Если вам не безразличны мэйнфреймы IBM, вы можете добавить небольшую справочную таблицу:
static char const *letters = "abcdefghijklkmnopqrstuvwxyz";
и использовать strchr
найти правильную позицию для каждой буквы.
Редактировать: Если вы используете C++, а не C (как сказал тег, когда я писал выше), вы можете немного упростить код за счет использования некоторого дополнительного хранилища (и, вероятно, немного более медленного):
std::string arr = "saaangeetha";
std::set<char> letters((arr.begin()), arr.end());
std::copy(letters.begin(), letters.end(), std::ostream_iterator<char>(std::cout, " "));
Тем не менее, обратите внимание, что, хотя они выглядят одинаково для тестового ввода, они могут вести себя по-разному - предыдущая версия выводит на экран все, кроме букв (и преобразует их все в нижний регистр), но это отличает верхний от нижнего регистра и показывает все не алфавитные символы в выводе также.
char *arr = "saangeetha";
arr
указывает на раздел только для чтения, где строковый литерал saangeetha
хранится. Таким образом, он не может быть изменен и является причиной ошибки нарушения доступа. Вместо этого вам нужно сделать -
char arr[] = "sangeetha"; // Now, the string literal can be modified because a copy is made.