注册 登录
编程论坛 C++教室

程序那里错了

flypampas 发布于 2006-09-22 16:27, 1564 次点击

/*
设一个环上有编号为 0~n-1 的 n 粒不同颜色的珠子
( 每粒珠子颜色用字母表示,n 粒珠子的颜色由输入的字符串表示)。
将环中某两粒珠子间剪开,环上珠子形成一个序列,然后按以下规则从序列
中取走珠子:首先从序列左端取走所有连续同色珠子;然后从序列右端在剩
下珠子中取走所有连续同色珠子,两者之和为该剪开处可取走珠子的粒数
。在不同位置剪开,能取走的珠子数不尽相同。
  本程序所求的是在环上哪个位置剪开,按上述规则可取
走的珠子粒数最多。程序中用数组存储字符串。例如,10 粒珠
子颜色对应字符串为"aaabbbadcc",从 0 号珠子前剪开,
序列为 aaabbbadcc,从左端取走 3 粒 a 色珠子,从右端取走 2 粒 c 色珠子,
共取走 5 粒珠子。若在 3 号珠子前剪开,即 bbbadccaaa 共可取走 6 粒珠子。
*/

#include<iostream>
#include<cstring>
using namespace std;

int count(char *s,int start,int end)
{
int i,c=0;
int step=(start>end)?-1:1;
char color=s[start];
for(i=start;s[i]==color;i+=step)
{
if((step>0&&i>end)||(step<0&&i<end)) break;
c++;
}
return c;
}

int main()
{
char t,s[120];
int i,j,c,len,maxc,cut=0;
cout<<"请输入环上代表不同颜色珠子字符串:";
cin>>s;
len=strlen(s);
maxc=0;
for(i=0;i<len;i++)
{
c=count(s,0,len-1);
if(c<len) c+=count(s,len-1,0);
if(c>maxc)
{
cut=i;
maxc=c;
}
t=s[0];
for(j=1;j<len;j++)
s[j-1]=s[j];
s[j]=t;
}
cout<<cut<<endl<<maxc<<endl;
return 0;
}
希望不要改变我的思想,帮我该下这个小程序。在下不胜感激!!

16 回复
#2
flypampas2006-09-22 16:57

斑竹帮帮忙啊

#3
踏魔狼2006-09-22 20:21

程序已改好,但你还是要多测试几次.

看来我又多管闭事了!

#include<iostream>
#include<cstring>
using namespace std;

int count(char *s,int start,int end)
{
int i,c=0;
int step=(start>end)?-1:1;
char color=s[start];
for(i=start;s[i]==color;i+=step)
{
if((step>0&&i>end)||(step<0&&i<end)) break;
c++;
}
return c;
}

int main()
{
char t,s[120];
int i,j,c,c1,c2,c3,temp=0,len,maxc,cut=0;
cout<<"请输入环上代表不同颜色珠子字符串:";
cin>>s;
len=strlen(s);
maxc=0;
for(i=0;i<len;i++)
{
c1=count(s,0,len-1);
c2=count(s,c1,len-1);
c3=count(s,len-1,0);
if( c2>c3)
c=c1+c2;
else
c=c1+c3;
temp+=c1;
if(c>maxc)
{
cut=temp;
maxc=c;
}
t=s[0];
for(j=0;j<len-c1;j++)
s[j]=s[c1+j];
for(;j<len;j++)
s[j]=t;
}
cout<<cut<<endl<<maxc<<endl;
return 0;
}

#4
wangxiang2006-09-22 20:29

我没看明白你的程序
就写了个
#include <iostream>
#include <string>
using namespace std;
int count(char *s,int length,int start)
{
const int len = 3*length;
char str[500];
for(int i = 0,j = 0;i <= len-1;i++,j++)
{
if(j == length)
j = 0;
str[i] =s[j];

}
str[i] = '\0';
int left = start+8,right = start+11;
const char char_left = str[left+1],char_right = str[right-1];
int n = 2;
for(i = left;i >= 0;i--)
{
if(str[i] == char_left)
n++;
else
break;
}
for(j = right;j <= len-1;j++)
{
if(str[j] == char_right)
n++;
else
break;
}
if(n == len)
n /=3;
return n;
}

int main()
{
char s[20];
cin>>s;
int len = strlen(s);
int n;
cin>>n;
int num = count(s,len,n);
cout<<num<<endl;
return 0;
}


#5
flypampas2006-09-22 22:14

第3楼的,你写的程序运行还是有错啊,
我运行了几种情况,当输入aassdffff时程序输出的是2 6
可是这种的正确答案是0 6
--------------------------------------
还有就是你为什么用c2,它有什么作用?
希望能得到你的回复!
还是谢谢你帮我看这个程序,再次感谢!

#6
flypampas2006-09-22 22:18
回4楼的:
我这个程序好像很好看明白啊!
我觉得它没有错误,可是运行起来它得到的结果不是想要的!
希望高手门进来指点指点,小弟不胜感激!
#7
flypampas2006-09-22 23:36
#8
wfpb2006-09-23 11:56

我也写了个

程序代码:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <assert.h>
using namespace std;


typedef int pos;


bool large(pair<pos,int>p1,pair<pos,int>p2)
{
    return p1.second>p2.second;
}


pair<pos,int> operator+(pair<pos,int>p1,pair<pos,int>p2)
{
    pair<pos,int>ptemp;
    ptemp.second=p1.second+p2.second;
    ptemp.first=p1.first;
    return ptemp;
}


void GetMost(string str)
{
    int len=str.length();
    int i;
    for(i=0;i<len;i++)  //首先找出一个位置(它本身的球色与前面一个不同)
    {
        if(str[i]!=str[((i-1)+len)%len])
            break;
    }
    if(i==len) //如果没个球的颜色一样,则任何位置都一样
    {
        for(int i=0;i<len;i++)
            cout<<i<<\" \";
        cout<<endl;
        return;            //此时便可返回,退出函数
    }


    vector<pair<pos,int> >vp;        //用来把个数与位置关联成一个pair的向量


    for(int j=i,count=0;count<len;j=(j+1)%10,count++)
    {
        static int t=0;
        static int p=count;
        if(t==0)
        {
            p=count;
            vp.push_back(pair<pos,int>(p,1));
            t=1;
        }


        if(str[j]==str[(j+1)%10])vp.back().second++;
        else t=0;
    }
    int vplen=vp.size();
    vector<pair<pos,int> >vecpair(vplen);
    for(int h=0;h<vplen;h++)
    {
        vecpair.at(h)=vp.at(h)+vp.at(((h-1)+vplen)%vplen);
    }
    sort(vecpair.begin(),vecpair.end(),large);
    for(int n=0;n<vplen;n++)
    {
        cout<<vecpair.at(n).first<<\" \"<<vecpair.at(n).second<<endl;
        if(vecpair.at((n+1)%vplen).second<vecpair.at(n).second)
            return;
    }
}



void M_Assert(string str)
{
    int len=str.length();
    for(int i=0;i<len;i++)
        assert(isalpha(str[i]));
}


int main(int argc, char* argv[])
{
    cout<<\"shuru:\"<<endl;
    string str;
    cin>>str;
    M_Assert(str);
    GetMost(str);
    return 0;
}

#9
wfpb2006-09-23 12:12
好象写多了点
pair<pos,int> &operator+(pair<pos,int>p1,pair<pos,int>p2)
//加个&好点
#10
wangxiang2006-09-23 13:24

不好意思,我看错问题了
#include <iostream>
#include <string>
using namespace std;
int count(char *s,int length,int start)
{
const int len = 3*length;
char str[500];
for(int i = 0,j = 0;i <= len-1;i++,j++)
{
if(j == length)
j = 0;
str[i] =s[j];

}
str[i] = '\0';
int left = start+length-2,right = start+length+1;
const char char_left = str[left+1],char_right = str[right-1];
int n = 2;
for(i = left;i >= 0;i--)
{
if(str[i] == char_left)
n++;
else
break;
}
for(j = right;j <= len-1;j++)
{
if(str[j] == char_right)
n++;
else
break;
}
if(n == len)
n /=3;
return n;
}

int main()
{
char s[20];
int a[20];
cin>>s;
int len = strlen(s);
for(int i = 0;i < len;i++)
a[i] = count(s,len,i);
int b = a[0];
for(int j = 1;j < len;j++)
if(a[j] > b)
b = a[j];
for(int k = 0;k < len;k++)
if(a[k] == b)
cout<<k<<endl<<b<<endl;
return 0;
}

#11
flypampas2006-09-23 18:27

能不能把我上面的那个程序改下??使它能正确的显示答案!

#12
wfpb2006-09-23 18:59
可以,不过把你的思想在你的函数中注明
#13
unicorn2006-09-24 12:56
以下是引用flypampas在2006-9-22 16:27:46的发言:

/*
设一个环上有编号为 0~n-1 的 n 粒不同颜色的珠子
( 每粒珠子颜色用字母表示,n 粒珠子的颜色由输入的字符串表示)。
将环中某两粒珠子间剪开,环上珠子形成一个序列,然后按以下规则从序列
中取走珠子:首先从序列左端取走所有连续同色珠子;然后从序列右端在剩
下珠子中取走所有连续同色珠子,两者之和为该剪开处可取走珠子的粒数
。在不同位置剪开,能取走的珠子数不尽相同。
  本程序所求的是在环上哪个位置剪开,按上述规则可取
走的珠子粒数最多。程序中用数组存储字符串。例如,10 粒珠
子颜色对应字符串为"aaabbbadcc",从 0 号珠子前剪开,
序列为 aaabbbadcc,从左端取走 3 粒 a 色珠子,从右端取走 2 粒 c 色珠子,
共取走 5 粒珠子。若在 3 号珠子前剪开,即 bbbadccaaa 共可取走 6 粒珠子。
*/

#include<iostream>
#include<cstring>
using namespace std;

int count(char *s,int start,int end)
{
int i,c=0;
int step=(start>end)?-1:1;
char color=s[start];
for(i=start;s[i]==color;i+=step)
{
if((step>0&&i>end)||(step<0&&i<end)) break;
c++;
}
return c;
}

int main()
{
char t,s[120];
int i,j,c,len,maxc,cut=0;
cout<<"请输入环上代表不同颜色珠子字符串:";
cin>>s;
len=strlen(s);
maxc=0;
for(i=0;i<len;i++)
{
c=count(s,0,len-1);
if(c<len) c+=count(s,len-1,0);
if(c>maxc)
{
cut=i;
maxc=c;
}
t=s[0]; // 从这里开始的字符串移动位置有问题,你可以在s[j]=t;后加cout<<s; 看看每次移动字符串的变化
for(j=1;j<len;j++)
s[j-1]=s[j];
s[j]=t;

// cout<<s<<endl;
}
cout<<cut<<endl<<maxc<<endl;
return 0;
}
希望不要改变我的思想,帮我该下这个小程序。在下不胜感激!!

其他的地方都没有错,就是字符串移动那里有问题
那里不是说移动顺序不对,是字符串有溢出的出现异常,结束标志应该是'\0'
.... ....
还有这个程序不完善 在得到同样的珠子的情况下应该输出所有的cut位置...

#14
DEMON_HUNTER2006-09-24 13:18

#include<iostream>
#include<cstring>
using namespace std;

int count(char *s,int start,int end)
{
int i,c=0;
int step=(start>end)?-1:1;
char color=s[start];
for(i=start;s[i]==color;i+=step)
{
if((step>0&&i>end)||(step<0&&i<end)) break;
c++;
}
return c;
}

int main()
{
char t,s[120];
int i,j,c,len,maxc,cut=0;
cout<<"请输入环上代表不同颜色珠子字符串:";
cin>>s;
len=strlen(s);
cout<<len<<endl;
getchar();
maxc=0;
for(i=0;i<len;i++)
{
c=count(s,0,len-1);
if(c<len) c+=count(s,len-1,0);
if(c>maxc)
{
cut=i;
maxc=c;
}
t=s[0];
for(j=1;j<len;j++)
s[j-1]=s[j];
//s[j]=t; 此处交换时,j已经变成len 而不是len-1,因此字符串的循环交替出现了问题
s[j-1]=t;
cout<<s<<endl;
getchar();
}
cout<<cut<<endl<<maxc<<endl;
return 0;
}

原来的程序写的不错!

#15
flypampas2006-09-25 01:18

非常感谢14楼的,那里改过来程序大致就好了。我看了好久都没有看出来啊,原来是这里错了,谢谢指点!
当然也要感谢上面回帖的人。
他们的方法也使我明白了许多。
-----------------------------
回13楼的:移动不讳产生异常,那只是移动s[120]中的一部分。我的程序还是楼上那个说的那一点。
得到同样的珠子的情况下输出所有的cut位置我想应该好实现。好像只需要定义cur[]数组应该可以解决吧!

#16
great_zlj2006-10-09 20:40
为什么头文件是这样,#include<iostream>
#include<cstring>
using namespace std;
而改成这样就不对,#include<iostream.h> #include<string.h>
#17
kular2011-06-30 18:42
回复 10楼 wangxiang
能不能写一下你的算法分析
1