当前位置: 代码迷 >> C语言 >> [讨论]第七次编程题目,大家支持一下
  详细解决方案

[讨论]第七次编程题目,大家支持一下

热度:243   发布时间:2007-03-11 21:16:51.0
以下是引用nuciewth在2007-3-11 19:25:16的发言:

干脆把我自己的行编译器程序贴出来,大家帮忙找不足之处.

#include<stdio.h>
#include<string.h>

int main()
{
#ifndef ONLINE_JUDGE
freopen ("hangbianyiqi.txt","r",stdin);
#endif

char c,str[300];
int i=0;
while(EOF!=(c=getchar()))//采取文件输入
{
if(c=='#')
{
if(i>0&&str[i-1]!='\n')
{
i--;//退格
}
}
else
{
if(c=='@')//可以先用一数组保存每一个换行符出现的位置,方便查找。
{

if(i>0)
{
while(str[--i]!='\n');
i++;
}

}
else
{
str[i++]=c;
}
}
}
str[i]='\0';
printf("%s\n",str);
return(0);
}



调式的话请在和程序同目录下建一hangbianyiqi.txt文件,里面输入你要测试的字符串.



----------------解决方案--------------------------------------------------------

我的第二题:无法突破高位数,还没找到问题在哪里。
# include <stdio.h>
# include <math.h>

unsigned long int xh,wei;
struct str
{
unsigned long int i;
struct str *next;
struct str *qian;
}*xulie2;
printxulie(struct str *xulie)
{
struct str *pa;
pa=xulie;
if(pa->next==0) printf("%ld ",(unsigned long int)pow(3,pa->i));
else
for(;pa!=0;pa=pa->next)
printf("%ld ",(unsigned long int)pow(3,pa->i));
}
struct str *hs(struct str *xulie)
{
struct str *a,*b,*c;
a=c=xulie;
if(xh+1==wei)
{
printxulie(a);
printf("1\n");
return(0);
}
else
if(xh+2==wei)
{
printxulie(a);
printf("3\n");
return(0);
}
else
if(xh+3==wei)
{
printxulie(a);
printf("3 1\n");
return(0);
}
else
{
for(;c->next!=0;c=c->next); //找到最后一位
xh=xh+4;
if(c->i>2) //前面补2
{
if(xh==wei)
{
printxulie(a);
printf("9\n");
return(0);
}
else
{
b=(struct str*)malloc(sizeof(struct str));
b->i=2;
b->next=0;
b->qian=c;
c->next=b;
c=b;
hs(a);
}
}
else
{ //检查后面是不是连续的,不是的话在断处补2
if(c->i==2)
{
if(c->qian==0)
{
c->i=3;
}
else
{
while(c->i==c->qian->i-1)
{
c=c->qian;
free(c->next);
}
c->i=c->i+1;
c->next=0;
}

if(xh==wei)
{
printxulie(a);
printf("\n");
return(0);
}
else
{
hs(a);
}
}
}
}
return(0);
}
main()
{
scanf("%ld",&wei);
while(wei>0)
{
wei=wei-1;
if(wei==1)
printf("1\n");
else if(wei==2) printf("3\n");
else if(wei==3) printf("3 1\n");
else
{
xh=4;
xulie2=(struct str*)malloc(sizeof(struct str));
xulie2->i=2;
xulie2->next=0;
xulie2->qian=0;
if(xh==wei)
{
printxulie(xulie2);
printf("\n");
}
else hs(xulie2);
}
scanf("%ld",&wei);
if(wei<2) break;
}
}


----------------解决方案--------------------------------------------------------
你应该考虑一下pow(3,i)所能算出的最大的数有可能限制了i
----------------解决方案--------------------------------------------------------
第二个注意一下题意,很容易理解错的.
我给出一部分序列.
{},{1},{3},{1,3},{9},{1,9},{3,9},{1,3,9},{27},{1,27},{3,27},{1,3,27},{9,27},{1,9,27},{3,9,27},{1,3,9,27},{81},{1,81},{3,81},{1,3,81},{9,81},{1,9,81},{3,9,81},{1,3,9,81},{1,27,81},{3,27,81},{1,3,27,81},{9,27,81},{1,9,27,81},{3,9,27,81},{1,3,9,27,81}
----------------解决方案--------------------------------------------------------
修改了部分代码,但是位数还是过不了60000多位,不管了,连机子重启的办法都用上来还解决不了,哎!
# include <stdio.h>
# include <math.h>
long int xh,wei;
struct str //结构里放的是3的次方数
{ //结果需要的都是3的n次方数,其实只要对0--n进行排序就行,只在输出时运算成3的次方
int i; //0就是3的0次方,i就是3的i次方
struct str *next;
struct str *qian;
}*xulie2,*a,*b,*c; //函数hs()都是对xulie2进行操作,借abc用来对xulie2进行添加或删除
printxulie(struct str *xulie) //输出最后结果集
{
struct str *pa;
pa=xulie;
if(pa->next==0) printf("%.0f ",pow(3,pa->i));
else
for(;pa!=0;pa=pa->next)
printf("%.0f ",pow(3,pa->i));
}
hs() //////函数,按从大到小的顺序逐个找出放到链表里
{
if(xh==wei-1) //此时的xh比wei小1时
{
printxulie(a); //直接输出序列,比如{9 7 6}
printf("1\n"); //然后后面补数1
return(0);
}
else
if(xh==wei-2) //因为输出结果要从大到小,所以补3的1次方3
{
printxulie(a);
printf("3\n");
return(0);
}
else
if(xh==wei-3) //前两次的不是要的结果,xh+3才是,所以补3和1
{
printxulie(a);
printf("3 1\n");
return(0);
}
else //前三次都不是,xh=xh+4
{
xh=xh+4; //比如当前序列是{9 7 6}序列各个数代表3的次方
if(c->i>2) //c即序列最后一个大与3的2次方9,比如上面的3的6次方就大于2次方
{
if(xh==wei) //{9 7 6}后应该是{9 7 6 0}{9 7 6 1}{9 7 6 1 0}这三个刚才进入此函数后比较过了不是
{ //而再后就应该是{9 7 6 2},所以是在序列后补2
printxulie(a);
printf("9\n"); //输出时补的2就应该是9了
return(0);
}
else
{ //补2在这里进行
b=(struct str*)malloc(sizeof(struct str));
b->i=2;
b->next=0;
b->qian=c;
c->next=b; //让c还是指向序列最后
c=b;
hs(); //再次进入hs()
}
}
else if(c->i==2) //如果序列不是{9 7 6}最后一个不是2,如{9 7 2}
{
if(c->qian==0)//如果序列只一个数{2}
c->i=3; //那么2升到3,{2 0}{2 1}{2 1 0}在函数开始就被排除
else //如果序列不是一个数如{9 7 4 3 2}
{ //如上c->i是2,c前面是3
while(c->i==c->qian->i-1)
{
c=c->qian; //把432都抛弃,因为97432前的974320 974321 9743210hs()前面比较过
free(c->next);
}
c->i=c->i+1; //让c指向7,此时序列是{9 7}
c->next=0;
}
if(xh==wei) //如果xh=wei
{
printxulie(a); //直接输出
printf("\n");
return(0);
}
else //继续进入hs()
hs();
}
}
return(0);
}
main()
{
struct str *pa;
scanf("%ld",&wei);
while(wei>1)
{ //{},{1},{3},{1 3},{9}
wei=wei-1; //减1是为了给空集{}占个位
if(wei==1) //减1后是1,那就是3的0次方1
printf("1\n");
else if(wei==2) printf("3\n");
else if(wei==3) printf("3 1\n");
else //从第四开始
{
xh=4; //xh从第4个开始
xulie2=(struct str*)malloc(sizeof(struct str)); //开始纪录链表
xulie2->i=2; //链表头一个一定要是最大数这样免去以后输出时排序
xulie2->next=0; //第一个放2代表3的2次方的2
xulie2->qian=0;
a=c=xulie2; //a,b,c定义成全局的,避免abc反复带入子函数时反复定义赋值
if(xh==wei) //直接输出
{
printxulie(xulie2);
printf("\n");
}
else hs(); //进入子函数hs()
}
scanf("%ld",&wei); //继续输入要找的第wei的子集
pa=xulie2;
if(wei<2) break;
else
for(;pa!=0;) //释放内存,原结果集的链表内容
{
pa=xulie2;
xulie2=pa->next;
free(pa);
}
}
}

[此贴子已经被作者于2007-3-13 10:13:28编辑过]


----------------解决方案--------------------------------------------------------

#include<iostream.h>
#include<stdio.h>

//本程序可处理的总编辑字符长度为250


int line_in(char *p,int max) // *p为输入缓冲区,max为行输入字符最大长度
//函数返回输入字符的个数
//输入函数先把用户输入所有字符存储下来
//在当前行为空的情况下直接按回车时结束程序
{
char ch;
int inlen=0; //inlen记录输入总字符数
cout<<"请输入数据,数据最大长度为"<<max<<" (当前行为空时按回车键结束)"<<endl;
scanf("%c",p);
if(*p=='\n')
return 0;
else
{
while((*(p+inlen++)!='\n' || *(p+inlen-2)!='\n') && inlen<max)
//当前行按回车时表示输入结束
{
scanf("%c",&ch);
*(p+inlen)=ch;
}
}
return (--inlen); //因为上面inlen多加了一次
}
void line_out(char *p,int inlen)//*p为输入字符串,inlen为输入字符串长度
{
int enter=0; //记录回车的地方
int outlen=0; //记录应输出字符位置
for(int i=0;i<inlen;i++) //按要求整理输入的字符
{
if(*(p+i)!='#'&&*(p+i)!='@') //把普通字符和特殊功能字符区分
{
if(*(p+i)=='\n')
{
if(outlen-1==enter)
continue;
else
{
enter=outlen; //记录最近一行结束的位置(即回车的地方)
//退行符将会用到
*(p+outlen++)=*(p+i); //用有用的字符覆盖掉应删除的字符
}
}
else *(p+outlen++)=*(p+i); //用有用的字符覆盖掉应删除的字符
}
else if(*(p+i)=='@') //处理退行符
{
if(enter==0) //首行出现退行符的情况
outlen=0;
else
outlen=enter+1;
}
else if(*(p+i)=='#') //处理退格符
{
if((outlen-1==enter && enter!=0) || outlen==0) //行首出现#的情况
continue;
else
outlen--; //一般情况
}
}
for(i=0;i<outlen;i++) //输出
cout<<*(p++);
cout<<endl;
}
int main()
{
int inlen;
char p[250];
int max=250;
inlen=line_in(p,max);
line_out(p,inlen);
return 0;
}
注释已经加了,思路应该很明显了

[此贴子已经被作者于2007-3-13 21:49:56编辑过]


----------------解决方案--------------------------------------------------------
你代码太多了,注释又少,实在很难看懂,能不能说一下你的思路,然后我在看看能不能看懂
----------------解决方案--------------------------------------------------------
回复:(iwfy)修改了部分代码,但是位数还是过不了60...
能不能说一下你的思路啊?
----------------解决方案--------------------------------------------------------
回复:(nuciewth)干脆把我自己的行编译器程序贴出来...
版主的很简洁啊!!!!!羡慕
----------------解决方案--------------------------------------------------------
to:zcs302,你的思路很不错,但是程序有BUG。
输入:a####
dfsdf#
sdfsfdsfsf
dfsfdf看看。

----------------解决方案--------------------------------------------------------
  相关解决方案