这个版本还算是比较清晰的,不过我也是搞了很久才弄成这样的。我的问题是:
1、在仅仅使用<iostream>的前提下,怎么定义delete_repeat函数最清晰且不容易出错?
2、在仅仅使用<iostream>的前提下,怎么定义这个函数能够让运行效率最高(至少比这个高)?
注意:这个函数不能打乱原数组中元素的顺序!
void delete_repeat(char s[], int& number_used)
{
int dimension = number_used; // dimension是数组t[]的实际维数
char t[MAX_DIM];
for(int i =0; i != dimension; ++i)// 将数组s[]中的元素复制到t[]中,并将s[]“清零”
{
t[i]=s[i];
s[i]='\0';
}
int i=0, j=0; // i是数组t[]的下标,而j是数组s[]的下标
while(i!=dimension)
{
// 在给s[j]赋值之前,先检查t[i]是否与s[j]前面的元素有重复
bool repeat = false;
for(int k=0; k<j; ++k)
{
if(t[i]==s[k])
{
repeat = true;
// 如果有重复,那么将i往右移一位
++i;
break;
}
}
if(repeat == false) // 没有重复的话,那么s[j]的值就是t[i]了,此时将i增加一位
{
s[j]=t[i];
++j;
++i;
}
}
number_used = j;
}
13 个解决方案
#1
这还要怎么折腾,用双链表最好了。
定义两个指针front,tail,同时指向数组首尾,tail开始向前移动,与首front的值进行比较:
直到front为null就结束,表示删除完毕!
定义两个指针front,tail,同时指向数组首尾,tail开始向前移动,与首front的值进行比较:
if(*tail == *front) 删掉tail,然后再往前移动,直到 tail = front 进行下一轮;
直到front为null就结束,表示删除完毕!
#2
来个人支持吧
#3
看lz的函数原型,目标数组是char类型的呀?char的表示范围是-128~127,用hash吧,方便,仅供参考:
void delete_repeat(char s[], int& number_used)
{
char already_in_s[256] = {0}, c;
int len = 0, i;
for(i = 0; i < number_used; ++i){
c = s[i] < 0 ? 256 + s[i] : s[i];
if(!already_in_s[c]){
s[len++] = c;
already_in_s[c] = 1;
}
}
number_used = len;
}
#4
void delete_repeat(char s[], int &number_used)
{
int pos =0,i,j;
for(i =0; i< number_used; i++){
for(j =0; j< i; j++){
if(s[i] == s[j]){
break;
}
}
if(i == j){
s[pos++] = s[i];
}
}
s[pos]='\0';
number_used = pos;
}
还是喜欢这样,空间也没浪费
#6
有木有中文版呀?英文版虽然也能看,但是看着费劲。
#7
仅仅使用iostream的话,你就需要找本《stl源码剖析》,抄抄stl里的*:sort+unique
#8
char s[] = {...} //反正就是初始化啦,里面塞一堆数据
std::unique(s, s+sizeof(s)/sizeof(char)); //重复元素删除完成~
里面的s可以换成任何支持前向迭代器的容器,不论是stl,还是你自己造,或者其他一些库里面的。当然容器的元素得能判断相等。
#9
排序完不就容易去冗了?数组要保持原顺序没关系啊,对index排序不就结了?
#include <iostream>
#include <algorithm>
#include <vector>
char testA[]="This is a random string and I am going to remove all but the very"
" first occurance of any characters contained.";
void delete_repeat(char s[], int& count)
{
std::vector<int> indexes;
indexes.reserve(count);
for(int i=0; i<count; ++i)
indexes.push_back(i);
std::stable_sort(indexes.begin(), indexes.end(), [s](int i, int j){ return s[i]<s[j];});
auto end=std::unique(indexes.begin(), indexes.end(), [s](int i, int j){return s[i]==s[j];});
std::sort(indexes.begin(), end);
for(int i=0; i<indexes.size(); ++i)
printf("%d\n", indexes[i]);
int j=0;
for(auto i=indexes.begin(); i<end; ++i)
s[j++]=s[*i];
count=end-indexes.begin();
}
int main(int argc, const char *argv[])
{
int cnt=sizeof(testA)-1;
delete_repeat(testA, cnt);
testA[cnt]='\0';
std::cout<<testA<<endl;
return 0;
}
#10
O(N)的采用计数机制,类似基数排序
记录每个字符,第一次出现的时候,记录到另一个表里。
记录每个字符,第一次出现的时候,记录到另一个表里。
#11
bieset<256>
#12
学习下,楼主用的方法好像比较死
#13
我了去,这都写不出来
#1
这还要怎么折腾,用双链表最好了。
定义两个指针front,tail,同时指向数组首尾,tail开始向前移动,与首front的值进行比较:
直到front为null就结束,表示删除完毕!
定义两个指针front,tail,同时指向数组首尾,tail开始向前移动,与首front的值进行比较:
if(*tail == *front) 删掉tail,然后再往前移动,直到 tail = front 进行下一轮;
直到front为null就结束,表示删除完毕!
#2
来个人支持吧
#3
看lz的函数原型,目标数组是char类型的呀?char的表示范围是-128~127,用hash吧,方便,仅供参考:
void delete_repeat(char s[], int& number_used)
{
char already_in_s[256] = {0}, c;
int len = 0, i;
for(i = 0; i < number_used; ++i){
c = s[i] < 0 ? 256 + s[i] : s[i];
if(!already_in_s[c]){
s[len++] = c;
already_in_s[c] = 1;
}
}
number_used = len;
}
#4
void delete_repeat(char s[], int &number_used)
{
int pos =0,i,j;
for(i =0; i< number_used; i++){
for(j =0; j< i; j++){
if(s[i] == s[j]){
break;
}
}
if(i == j){
s[pos++] = s[i];
}
}
s[pos]='\0';
number_used = pos;
}
还是喜欢这样,空间也没浪费
#5
#6
有木有中文版呀?英文版虽然也能看,但是看着费劲。
#7
仅仅使用iostream的话,你就需要找本《stl源码剖析》,抄抄stl里的*:sort+unique
#8
char s[] = {...} //反正就是初始化啦,里面塞一堆数据
std::unique(s, s+sizeof(s)/sizeof(char)); //重复元素删除完成~
里面的s可以换成任何支持前向迭代器的容器,不论是stl,还是你自己造,或者其他一些库里面的。当然容器的元素得能判断相等。
#9
排序完不就容易去冗了?数组要保持原顺序没关系啊,对index排序不就结了?
#include <iostream>
#include <algorithm>
#include <vector>
char testA[]="This is a random string and I am going to remove all but the very"
" first occurance of any characters contained.";
void delete_repeat(char s[], int& count)
{
std::vector<int> indexes;
indexes.reserve(count);
for(int i=0; i<count; ++i)
indexes.push_back(i);
std::stable_sort(indexes.begin(), indexes.end(), [s](int i, int j){ return s[i]<s[j];});
auto end=std::unique(indexes.begin(), indexes.end(), [s](int i, int j){return s[i]==s[j];});
std::sort(indexes.begin(), end);
for(int i=0; i<indexes.size(); ++i)
printf("%d\n", indexes[i]);
int j=0;
for(auto i=indexes.begin(); i<end; ++i)
s[j++]=s[*i];
count=end-indexes.begin();
}
int main(int argc, const char *argv[])
{
int cnt=sizeof(testA)-1;
delete_repeat(testA, cnt);
testA[cnt]='\0';
std::cout<<testA<<endl;
return 0;
}
#10
O(N)的采用计数机制,类似基数排序
记录每个字符,第一次出现的时候,记录到另一个表里。
记录每个字符,第一次出现的时候,记录到另一个表里。
#11
bieset<256>
#12
学习下,楼主用的方法好像比较死
#13
我了去,这都写不出来