老师出的程序题,不会啊,谁能帮帮忙```先谢了```
输入产品编号
如:A1-5,B2-10
为了方便用户输入,程序可采用简写输入
输入 输出
A1-10 A1-10
A1-7,8 A1-7 A1-8
B1-2'4 B1-2 B1-3 B1-4
C2-2'4,6'8 C2-2 C2-3 C2-4 C2-6 C2-7 C2-8
问题点数:20、回复次数:25Top
1 楼taodm((不能收CSDN社区短信息,请莫浪费精力))回复于 2006-11-16 09:48:53 得分 0
不就是根据-找出前缀,根据,找出每个数字组,如果数字组里有'就把数字组拆解成2个数字嘛。
有啥难的。
自己认真做。
这个题练手非常好!想进步就自己做。Top
2 楼shl6894(越学越无知)回复于 2006-11-16 09:55:52 得分 0
可以有好多方法啊,IO控制流。不过如果是最开始学习的话还是认真研究以下,课本有很多例子的。Top
3 楼hzjtyh(小母牛背跃式跳高)回复于 2006-11-16 09:56:47 得分 0
貌似昨天有过这样的帖子
同一个人?
难道是同学?Top
4 楼pottichu(拉拉是头猪)回复于 2006-11-16 12:46:47 得分 0
作业题,不帮忙,哈哈。Top
5 楼venus224(呵呵)回复于 2006-11-16 14:58:51 得分 0
偶做不出来啊```
帮个忙啊?
马上就要上交了喔```
我保证回去好好研究```呵呵```Top
6 楼taodm((不能收CSDN社区短信息,请莫浪费精力))回复于 2006-11-16 15:02:08 得分 0
做出一部分也比拿别人的交差强。
难道A1-10 A1-10
A1-7,8 A1-7 A1-8
这2个你也做不出?Top
7 楼wanfustudio(雁南飞:知识之败,慕虚名而不务潜修也)回复于 2006-11-16 15:17:53 得分 0
楼上的快气坏了
楼主自己试试
Top
8 楼kenneth_lueng()回复于 2006-11-16 15:23:11 得分 0
练手不不错的一道题,还涉及到词法分析的问题Top
9 楼weiyiabout()回复于 2006-11-16 15:34:17 得分 0
怎么拿老师上课出的题过来问大家呢?自己做才能有提高啊Top
10 楼cillin(是这样吗?)回复于 2006-11-16 15:42:29 得分 0
晕,要做出来还是很简单的撒。
本来想贴给你的。可是楼主要别人帮做作业还给这么少的分?Top
11 楼k1x2d3(一冲云天)回复于 2006-11-16 16:25:59 得分 0
写了一个很笨的程序,哪位高手写个高效的程序实现?Top
12 楼HoBoss(学徒)回复于 2006-11-16 18:06:44 得分 0
等高手Top
13 楼undiaoyao(Stanley)回复于 2006-11-16 18:50:54 得分 0
/*不是学计算机的,初学C++,不过还是凑合着写一个出来。呵呵*/
/*输入产品编号
如:A1-5,B2-10
为了方便用户输入,程序可采用简写输入
输入 输出
A1-10 A1-10
A1-7,8 A1-7 A1-8
B1-2'4 B1-2 B1-3 B1-4
C2-2'4,6'8 C2-2 C2-3 C2-4 C2-6 C2-7 C2-8*/
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
string expandStr(string&); //展开1'5这样的串
int toInt(const string&);
string toStr(const int);
int main()
{
string str;
string afterStr;
cout<<"Insert[q to quit]: ";
cin>>str;
while(str!="q")
{
afterStr = expandStr(str);
cout<<"\n>> Output:"<<endl;
cout<<">> "<<afterStr<<endl;
cout<<"Insert[q to quit]: ";
cin>>str;
}
return 0;
}
string expandStr(string& origStr)
{
string afterStr = "";
string head = ""; //型号的头部
string tmpStr = "";
vector<string> container; //装载每个型号的数字部分
string::iterator beg = origStr.begin();
string::iterator end = origStr.end();
//for(string::iterator iter = beg; iter != end; ++iter)
while('-' != *beg)
{
head.push_back(*beg);
++beg;
}
head += "-";
++beg;
for( ; beg < end; ++beg)
{
if( '\'' != *beg && ',' != *beg)
tmpStr.push_back(*beg);
else if(',' == *beg)
{
container.push_back(tmpStr);
tmpStr.clear();
}
else if('\'' == *beg)
{
int first = toInt(tmpStr);
int last = 0;
tmpStr.clear();
++beg;
//此处可以用一个flag来标记读到的是符号 ' 左边还是右边的数
//这样就可以不用嵌套while循环找int last了
//为了方便理解,多用一个while,时间复杂度没怎么增加
while(',' != *beg && beg != end)
{
tmpStr.push_back(*beg);
++beg;
}
last = toInt(tmpStr);
tmpStr.clear();
//把符号 ' 分开的两个数字展开。
//例如12'15展开成12 13 14 15,
//将展开后的数字转换成字符按照顺序放到container里面
for(int i=first; i<=last; ++i)
container.push_back(toStr(i));
}
}
if(!tmpStr.empty())
container.push_back(tmpStr);
//生成最终展开的结果字符串
for(vector<string>::iterator iter = container.begin();
iter != container.end();
++iter)
afterStr = afterStr + head + *iter + " ";
return afterStr + "\n";
}
int toInt(const string& str)
{
int integer;
stringstream tmp;
tmp<<str;
tmp>>integer;
return integer;
}
string toStr(const int integer)
{
string str;
stringstream tmp;
tmp<<integer;
tmp>>str;
return str;
}Top
14 楼rubyhlp0925()回复于 2006-11-16 19:43:17 得分 0
楼上的写的这么复杂,感觉有点乱,而且用vc编译不通过,head.push_back(*beg);tmpStr.clear();没有函数体Top
15 楼k1x2d3(一冲云天)回复于 2006-11-16 20:25:09 得分 0
楼上那位的方法不错,不过不知道为什么编译找不到pushback和clear函数?
但可以用insert和erase函数来代替Top
16 楼lottotfn()回复于 2006-11-16 20:25:11 得分 0
不就是简单的字符匹配么?Top
17 楼undiaoyao(Stanley)回复于 2006-11-16 23:04:20 得分 0
呵呵我是看C++Class Reference写的
在Dev C++ 4992里面调试通过的
下午要上课没仔细看看,确实复杂了。
这几天在看正则表达式,不过不会用,用那个来匹配应该很容易很容易的
不是专业水平,见谅,呵呵Top
18 楼doon(vecodo)回复于 2006-11-17 03:26:50 得分 0
这是我仿照 lex和yacc的结构手写的一个方法,用到了编译原理的一些知识,基本的过程的过程是这样的:
词法分析 -- 语法分析 -- 形成输出
lexer为词法分析程序
parser为语法分析程序
楼主可以参考参考,但是最好不要当作作业,恐怕老师不会相信你
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
//一个简单的语法分析器
#define TYPE_NONE 0 //未知
#define TYPE_NO_HEAD 1 //编号头
#define TYPE_NO 2 //编号
#define TYPE_LINK 3 //连接符号 '
#define TYPE_STEP 4 //可选符号 ,
struct VALUE{ //值
char szText[50];
int ival;
int type;
};
//词法分析器
int lexer(char** pstrIn,VALUE *pval)
{
//规则定义如下:
//如果开头是字母,则是编号头,并以'-'结束
//如果开头是数字,则是编号
//如果开头是','或者'\'',是规则LINK和STEP
//第一步选用规则
int type = TYPE_NONE;
if((**pstrIn>='A' && **pstrIn<='Z') || (**pstrIn>='a' && **pstrIn<='z'))
{
for(int i=0;i<50 && **pstrIn && **pstrIn!='-'; (*pstrIn)++,i++)
pval->szText[i] = **pstrIn;
if(**pstrIn) (*pstrIn)++;
pval->szText[i++] = '-';
pval->szText[i] = 0;
pval->type = TYPE_NO_HEAD;
return TYPE_NO_HEAD;
}
else if(**pstrIn>='0' && **pstrIn<='9') {
for(int i=0;i<50 && **pstrIn && **pstrIn>='0' && **pstrIn<='9';(*pstrIn)++,i++)
pval->szText[i] = **pstrIn;
pval->szText[i] = 0;
pval->ival = atoi(pval->szText);
pval->type = TYPE_NO;
return TYPE_NO;
}
else if(**pstrIn==',')
{
pval->szText[0] = ',';
pval->szText[1] = '\0';
pval->type = TYPE_STEP;
(*pstrIn)++;
return TYPE_STEP;
}
else if(**pstrIn=='\'')
{
pval->szText[0] = '\'';
pval->szText[1] = '\0';
pval->type = TYPE_LINK;
(*pstrIn)++;
return TYPE_LINK;
}
return TYPE_NONE;
}
void parser(char* strSrc)
{
//负责语法处理
//语法的格式有:
// HEADER NO
// HEADER NO LINK(') NO
// HEADER NO STEP(,) NO [STEP(,) NO]
// HEADER NO LINK(') NO [STEP(,) NO|STEP(,) NO LINK(') NO]
//创建语法堆栈
VALUE valueStack[10];
int sstop=0; //stack top
//开始解析
while(*strSrc)
{
//获得第一个堆栈的值
if(lexer(&strSrc,valueStack+sstop))
{
if(sstop==0) //空的堆栈,压站
{
sstop ++;
}
else{
switch(valueStack[sstop-1].type)
{
case TYPE_NO_HEAD: //直接打印
if(valueStack[sstop].type==TYPE_NO){
printf("%s%s\n",valueStack[sstop-1].szText,valueStack[sstop].szText);
sstop ++; //将NO压入栈
}
else if(valueStack[sstop].type==TYPE_NO_HEAD)
{
//以前的编号头被当前的编号头取代
memcpy(valueStack+sstop-1,valueStack+sstop,sizeof(VALUE));
//sstop --;
}
//else 出现了语法错误,试图忽略当前的
break;
case TYPE_NO: //将当前的打印
if(valueStack[sstop].type == TYPE_LINK ||
valueStack[sstop].type == TYPE_STEP) //只接受这两种
sstop ++; //将当前的操作入站
else if(valueStack[sstop].type==TYPE_NO_HEAD) //新的编号头,替换以前的编号头
{
memcpy(valueStack+sstop-2,valueStack+sstop,sizeof(VALUE));
sstop -= 1;
}
/*else //出现语法错误,但是我们将试图忽略它
break;
*/
break;
case TYPE_STEP: // ,
if(valueStack[sstop].type==TYPE_NO) // 数字编号,将当前的打印,并退栈
{
printf("%s%s\n",valueStack[sstop-3].szText,valueStack[sstop].szText);
sstop -= 2; //退栈到编号头
}
else if(valueStack[sstop].type==TYPE_NO_HEAD) //新的编号头,替换以前的编号头
{
memcpy(valueStack+sstop-3,valueStack+sstop,sizeof(VALUE));
sstop -= 2;
}
//else 发生语法错误,试图忽略
break;
case TYPE_LINK:
if(valueStack[sstop].type==TYPE_NO)
{ //依次打印从'前到其后的数据
for(int i=valueStack[sstop-2].ival+1;i<=valueStack[sstop].ival;i++)
printf("%s%d\n",valueStack[sstop-3].szText,i);
//替换数字栈
sstop -= 2; //退站
}
else if(valueStack[sstop].type==TYPE_NO_HEAD) //新的编号头,替换以前的编号头
{
memcpy(valueStack+sstop-3,valueStack+sstop,sizeof(VALUE));
sstop -= 2; //退栈
}
//else 发生语法错误,试图忽略
break;
}
}
}
else
{
strSrc++; //转移到下个字符试图获得正确的数据
}
}
}
int main(int argc, char* argv[])
{
char szText[100];
while(1){
printf("Input product Number(type \"quit\" to quit):");
for(int i=0;i<100 && (szText[i]=getchar())!='\n'; i++);
szText[i]='\0';
if(strcmp(szText,"quit")==0)
break;
parser(szText);
}
return 0;
}
/*
程序的输入例子和输出结果
Input product Number(type "quit" to quit):A1-10 A1-7,8 B1-2'4 C2-2'4,6'8
A1-10
A1-7
A1-8
B1-2
B1-3
B1-4
C2-2
C2-3
C2-4
C2-6
C2-7
C2-8
Input product Number(type "quit" to quit):
*/Top
19 楼doon(vecodo)回复于 2006-11-17 03:56:36 得分 0
再唠叨一下,可以用lex和yacc工具生成代码:
lex的文件
l.lex:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
extern int yylval;
char szHeader[100];
%}
%%
"quit" {return 0;}
[a-zA-Z][a-zA-Z0-9]*[-] {strcpy(szHeader,yytext);return NO_HEAD;}
[0-9]+ {yylval=atoi(yytext);return NO;}
"," { return STEP;}
"\'" { return LINK;}
. ; /*ignore*/
%%
yacc 的文件
l.y
%{
#include <stdlib.h>
#include <stdio.h>
int yylex(void);
extern char szHeader[100];
%}
%token NO_HEAD NO LINK STEP
%%
coding_list: coding
| coding_list coding
;
coding: NO_HEAD NO {printf("%s%d\n",szHeader,$2); $$=$2;}
| coding STEP NO {printf("%s%d",szHeader,$3);}
| coding LINK NO {
int i;
for(i=$$+1;i<=$3;i++)
{
printf("%s%d\n",szHeader,i);
}
printf("\n");
}
;
%%
int main(int argc,char* argv[])
{
yyparse();
return 0;
}
void yyerror(const char* s)
{
printf("error:%s\n",s);
}
int yywrap()
{
return 1;
}
在RedHat上编译,使用下面的命令
$ lex l.lex
$ yacc -d l.y
$ gcc -c lex.yy.c
$ gcc -c y.tab.c
$ gcc -o -l lex.yy.o y.tab.o
然后运行
$ ./l
/*输入*/ A1-10 A1-7,8 B1-2'4 C1-2'4,7'9
/*以下是输出*/
A1-10
A1-7
A1-8
B1-2
B1-3
B1-4
C1-2
C1-3
C1-4
C1-7
C1-8
C1-9
/*退出*/quit
$Top
20 楼vbyzc()回复于 2006-11-17 10:19:19 得分 0
这么复杂Top
21 楼uglykoala(碧波)回复于 2006-11-17 11:47:43 得分 0
好久没有玩C了。忘记C的用法了。呵呵
用C#简单写了一个。
没有用正则表达试判断。
所以输入要正确。而且,不能输入9以上的数字。
例如你可以这样输入C2-2'4,6'8
结果是:
C2-2
C2-3
C2-4
C2-6
C2-7
C2-8
using System;
using System.Collections;
namespace 输入产品编号
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
//
Queue myQueue = new Queue();
Stack myStack = new Stack();
string strInput= Console.ReadLine();
int strlength=strInput.Length;
int position=strInput.IndexOf("-");
string frontstr=strInput.Substring(0,position);
string tailstr=strInput.Substring(position+1,strlength-position-1);
tailstr=tailstr+",";
char testLetter;
int max;
int min;
for(int i=0;i<tailstr.Length;i++)
{
testLetter=tailstr[i];
switch(testLetter)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':myStack.Push(testLetter);break;
case ',':max=int.Parse(myStack.Pop().ToString());
min=int.Parse(myStack.Pop().ToString());
int j=min;
while(j<(max+1))
{
myQueue.Enqueue(j);
j=j+1;
}
myStack.Clear();
break;
}
}
int queueLength= myQueue.Count;
for(int k=0;k<queueLength;k++)
{
//Console.WriteLine(frontstr+"-"+((int)myQueue.Dequeue()).ToString());
Console.WriteLine(frontstr+"-"+int.Parse(myQueue.Dequeue().ToString()));
}
}
}
}
Top
22 楼kaishin()回复于 2006-11-17 23:21:52 得分 0
新手……
人外有人!
哭泣ing……
我何时才能成为高手呢?!Top
23 楼WXT1984(汇编菜鸟)回复于 2006-11-21 14:46:23 得分 0
我也凑个热闹。。不过用的python :P c/c++全忘记了- -b
input = raw_input("Please input the string:")
header = input[0:3]
number = [elem.split("'") for elem in input[3:].split(',')]
for i in range (0,len(number)):
number[i] = range(int(number[i][0]),int(number[i][-1])+1)
for a in number:
print [header+"%d"%(elem) for elem in a]
Top
24 楼c4pt0r()回复于 2006-11-21 20:27:07 得分 0
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
int putintovector(vector<string>& a,string cmdline,char s);
void print(string beg,string end,string name);
void dealthestring(vector<string> a,string name);
main()
{
string cmdline,name,b,e,a;
const char* chNum;
int intNum,pos ;
vector<string> vecA;
cin>>cmdline;
pos=cmdline.find('-');
name=cmdline.substr(0,pos);
a=cmdline.substr(pos+1,cmdline.size()-pos);
putintovector(vecA,a,',');
dealthestring(vecA,name);
system("pause");
}
int putintovector(vector<string>& a,string cmdline,char s)
{
int i=0,n=0,b=0;
string tmp;
for (i=0;i<cmdline.size();i++)
{
if (cmdline[i]==s)
{
n++;
tmp=cmdline.substr(b,i-b);
a.push_back(tmp);
b=++i;
}
}
tmp=cmdline.substr(b,i-b);
a.push_back(tmp);
return n;
}
void print(string beg,string end,string name) //打印结果
{
const char* chNumB ;
const char* chNumE;
int intNumB,intNumE;
chNumB=beg.c_str();
chNumE=end.c_str();
intNumB=atoi(chNumB);
intNumE=atoi(chNumE);
for (int i=intNumB;i<=intNumE;i++) cout<<name<<"-"<<i<<" ";
}
void dealthestring(vector<string> a,string name) //处理字符串
{
string tmp,b,e;
int pos;
for (int i=0;i<a.size();i++)
{
tmp=a[i];
pos=tmp.find('~');
if (pos!=0)
{
b=tmp.substr(0,pos);
e=tmp.substr(pos+1,tmp.size()-pos);
cout<<endl;
print(b,e,name);
}
}
}
刚开始学C++~~顺手写了一个~~调试通过了~~因为以前C写多了~还是用了C的库函数~~~见笑Top
25 楼cc0505(菜鸟努力进阶中~~)回复于 2006-11-22 14:43:58 得分 0
C4Pt正解Top




