首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

小弟我认为相当难的有关问题.

2012-02-12 
我认为相当难的问题...只可以用stdio.h和string.h里的命令我都快疯了,一点不会....Universal Product Code

我认为相当难的问题...
只可以用stdio.h和string.h里的命令
我都快疯了,一点不会....

Universal Product Code Analysis

In this assignment you will write a C program to analyze a UPC
Barcode. 
See: http://en.wikipedia.org/wiki/Universal_Product_Code for details.
There are a variety of UPC codes. 
We will only analyze the 12 digit variety.
A barcode is printed on many items and is scanned in a shop for pricing and
inventory. 
It consists of a sequence of black and white bars of different
widths. 
The widths encode a sequence of 12 digits.

Here is a barcode for the UPC, 036000291452. As shown, there is a guard
at the start, a guard in the middle, and a guard at the end.



A black bar can be of width 1, 2, 3 or 4 and is represented by '1', '11',
'111' or '1111' Similarly a white bar is represented by '0', '00', '000' or
'0000'. 
A valid barcode consists of the left guard, 101, a string of 42 '1's
or '0's representing the left 6 digits, a middle guard, 01010, a string of
42' 1's or '0's representing the right 6 digits, and the right guard, 101.
Each UPC digit is represented by 7 '1's or '0's.
 Example: If 3 occurs in the
left 6 digits it is represented by 0111101, meaning a white bar of width 1,
a black bar of width 4, a white bar of width 1 and a black bar of width 1.
If 3 occurs in the right 6 digits it is represented by 1000010, (that is,
the "negative" of 0111101). 
Your program will input a barcode from the file,
"barcode.dat". For the above barcode the file barcode.dat contains:

10100011010111101010111100011010001101000110
101010110110011101001100110101110010011101101100101

Your program will analyze this and convert it into the UPC code,
0 3 6 0 0 0 2 9 1 4 5 2.

The left values for all the ten digits are given by:

0 = 0001101, 1 = 0011001, 2 = 0010011, 3 = 0111101, 4 = 0100011,
5 = 0110001, 6 = 0101111, 7 = 0111011, 8 = 0110111, 9 = 0001011

These values can be represented by joining them into the string:

"00011010011001001001101111010100
01101100010101111011101101101110001011"

Note that the left value corresponding to digit d starts at position
7*d, and has length 7.

Similarly the right values is:

"1110010110011011011001000010101110
010011101010000100010010010001110100"

Your program will read a barcode consisting of 95 '0's or '1's, from the
file, barcode.dat,  
and convert it into a 12 digit UPC. Assume that
there are no errors in the barcode.

Your program should use these functions:

main : read the barcode from barcode.dat, print its left and right parts,
  call analyze, and print the resulting UPC digits.

void analyze(char barcode[ ], int upc[ ]): analyze the barcode given by
the first parameter and convert into 12 digits,
 in the second parameter.
Calls convert.

int convert(char barcode[ ], int n, char code[ ]): convert the 7 barcode
characters starting at position n to a single UPC digit.
 The first parameter,
barcode, should match part of the third parameter, code (which will either
be a left value string, or a right value string).
 The position of the
match can be used to calculate the UPC digit. 
Calls match.

int match (char a[ ], int aStart, char b[ ], int bStart, int n): match 'n'
characters of string a, 
starting at index aStart with n characters of
string b starting at index bStart. 
If successful, return 1 else
return 0.

The program should output the final UPC digits. Here is a sample output.

Barcode Analysis

Left part: 0001101 0111101 0111011 0100011 0101111 0101111
Right part: 1110010 1001000 1000010 1110010 1011100 1110100



UPC Code is: 0 3 7 4 6 6 0 8 3 0 4 9

[解决办法]
建议:
1。你要看懂英文的意思。如果看不懂就多读几遍。

2。涉及到打开读入的*。BAT文件,如果把里面的数据放到一个临时的存储区里面。然后从临时的存储区按照要求进行数据处理就可以了。
[解决办法]
他已经说得很明白了,连函数名和调用关系都指出来了,因该没什么难度了。

C/C++ code
#define CODE_LEN 70        //0~9 barcode的长度char szBarcodeLeft[CODE_LEN]="00011010011001001001101111010100                               01101100010101111011101101101110001011";             //左边6个barcode编码0~9char szBarcodeRigth[CODE_LEN]="1110010110011011011001000010101110                                010011101010000100010010010001110100";             //右边6个barcode编码0~9#define SINGLE_LEN 7       //单个barcode长度void analyze(char barcode[],int upc[]){  int nUIndex=0;      //数组upc的索引  int n=4;            //由于完整的barcode前面有3个guard,所以从第四个开始  int nResult=-1;     //convert返回的结果,小于零表示匹配失败,大于零则等于匹配的结果  for(;nUIndex<=5;n+=SINGLE_LEN)  {    nResult=convert(barcode,n,szBarcodeLeft);     //转换左边6个    if(nResult>=0)    {      upc[nUIndex]=nResult;          //将转换的结果装入upc数组      nUIndex++;    }    else    {      printf("no match barcode!")    //他说假设barcode是正确的,所以一旦出现这种情况      break;                         //要么是读文件出错,要么是这段代码有问题。下同    }  }  for(n=51;nUIndex<=11;n+=SINGLE_LEN)    //转换右边6个  {    nResult=convert(barcode,n,szBarcodeRigth);    if(nResult>=0)    {      upc[nUIndex]=nResult;      nUIndex++;    }    else    {      printf("no match barcode!")      break;    }  }}int convert(char barcode[],int n,char code[]){   int nIndex=0;           for(int i=0;i<CODE_LEN-SINGLE_LEN;i+=SINGLE_LEN)   //在数组中查找有无匹配   {     if(match(barcode,n,code,i,SINGLE_LEN)            //从0查起,直到查到匹配,这时的nIndex就是结果       return nIndex;     nIndex++;   }   return -1;                                         //没查到就返回无效值}int match(char a[],int aStart,char b[],int bStart,int n){  while(n>0)  {    if(a[aStart]!=b[bStart])                          //每次连续匹配7个,有一个不同就返回0      return 0;    aStart++;    bStart++;    n--;  }  return 1;                                           //否则返回找到}
[解决办法]
我写了部分的代码,个人觉得已经把文章的要求理解透彻了
有点要注意就是,7个二进制的位应该对应的是2的7次方,但是这里就是0到9,有固定的转换编码,而且前6个的转换编码和后面6个是成反码的
我写了main和后面的一个转换的,再后面的两个很简单 了

C/C++ code
// barcode.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <bitset.h>void analyze(char barcode[], int upc[]);int convert(char barcode[], int n, char code[]); int match(char a[], int aStart, char b[], int bStart, int n);     int main(void) {   FILE *stream;   char Buffer[85];   int  ch;   // Open file to read line from:   fopen("barcode.dat", "r" );   if( stream == NULL )      exit( 0 );   // 读取相应的左边的45个字符进Buffer[0--41], 右边的45个字符进rBuffer[42--83]   ch = fgetc( stream );   for(int i=0; (i < 95 ) && ( feof( stream ) == 0 ); i++ ) {       if ( (i > 2) && (i < 45) ) {           Buffer[i - 3] = (char)ch;           ch = fgetc( stream );       }       if ( (i > 49) && (i < 92) ) {           Buffer[i - 8] = (char)ch;           ch = fgetc( stream );       }   }   Buffer[84] = '\0';      //打印相应的左右值   printf("Buffer = %s \n", Buffer);      int upc[12] = {0}; //初始化每一个upc为0// 下面就是自己设计upc的转化了,和打印// 这里我省去了   fclose( stream );   return 0;}void analyze(char barcode[], int upc[]){    // 把barcode中每7个字符分析之后的值存入upc之中。    // analyze   the   barcode   given   by     // the   first   parameter   and   convert   into   12   digits.    // 分别把其中的每7位按照顺序存入upc数组中就是了    static int j = 0;    for (int i = 0; i < 84; i++) {                upc[j] += barcode[i];        upc[j] = (upc[j] << 1);        if ( !((i+1)%7) ) {            j++;        }    }    //施行转换,根据题目的要求,前面6个数字的0~9转化码与后面6个数字的转化码是不一样的,    //其实仔细看一下就可以发现,其实转化码前6个与后6个是互为反码。    //The   left   values   for   all   the   ten   digits   are   given   by:     //0   =   0001101,   1   =   0011001,   2   =   0010011,   3   =   0111101,   4   =   0100011,     //5   =   0110001,   6   =   0101111,   7   =   0111011,   8   =   0110111,   9   =   0001011     // 右边取反码    for (int i = 0; i < 6; i++) {        switch (upc[i]) {            case 0001101:                upc[i] = 0;                break;            case 0011001:                upc[i] = 1;                break;            case 0010011:                upc[i] = 2;                break;            case 0111101:                upc[i] = 3;                break;            case 0100011:                upc[i] = 4;                break;            case 0110001:                upc[i] = 5;                break;            case 0101111:                upc[i] = 6;                break;            case 0111011:                upc[i] = 7;                break;            case 0110111:                upc[i] = 8;                break;            case 0001011:                upc[i] = 9;                break;            default:                puts("不符合转换码规则,程序推出!");                exit(0);        }    }    for (int i = 6; i < 12; i++) {        switch (upc[i]) {            case 0001101^1111111:  //这里很简单,由于从第七个upc值到第十二个值的转换码对应着                                  //前6个的反码,我们让其值跟7个1异或便是对应的转换码                upc[i] = 0;                break;            case 0011001^1111111:                upc[i] = 1;                break;            case 0010011^1111111:                upc[i] = 2;                break;            case 0111101^1111111:                upc[i] = 3;                break;            case 0100011^1111111:                upc[i] = 4;                break;            case 0110001^1111111:                upc[i] = 5;                break;            case 0101111^1111111:                upc[i] = 6;                break;            case 0111011^1111111:                upc[i] = 7;                break;            case 0110111^1111111:                upc[i] = 8;                break;            case 0001011^1111111:                upc[i] = 9;                break;            default:                puts("不符合转换码规则,程序推出!");                exit(0);        }    }    for (int i = 0; i < 12; i++)        printf ("UPC   Code   is: %6d", upc[i]);    puts("");}//先写这么多,觉得可以就给分吧//下面的很好实现了int convert(char barcode[], int n, char code[]){}int match(char a[], int aStart, char b[], int bStart, int n){} 


[解决办法]
条形码
//开始标记:101
左边: 6个7位二进制 每一个7位二进制转换成以各数字(0--9) 根据左字典
中间标记01010
右边 6个7位二进制 每一个7位二进制转换成以各数字(0--9) 根据左字典
结束标记 101
//left字典
0 = 0001101, 1 = 0011001, 2 = 0010011, 3 = 0111101, 4 = 0100011, 
5 = 0110001, 6 = 0101111, 7 = 0111011, 8 = 0110111, 9 = 0001011 

右字典可以根据左字典得到,
右字典和左字典刚好互补,
如 左字典 0 = 0001101, 1 = 0011001
那么右字典 0 = 1110010 1 = 1100110


[解决办法]

C/C++ code
 
#include "string.h"
#include "stdio.h"

enum NUMBER {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};

struct
{
NUMBER index;
char code[8];
} left[10] =
{
ZERO, "0001101",
ONE, "0011001",
TWO, "0010011",
THREE, "0111101",
FOUR, "0100011",
FIVE, "0110001",
SIX, "0101111",
SEVEN, "0111011",
EIGHT, "0110111",
NINE, "0001011",
};

struct{
NUMBER index;
char code[8];
} right[10] =
{
ZERO, "1110010",
ONE, "1100110",
TWO, "1101100",
THREE, "1000010",
FOUR, "1011100",
FIVE, "1001110",
SIX, "1010000",
SEVEN, "1000100",
EIGHT, "1001000",
NINE, "1110100",
};

void analyze(char barcode[], int upc[]);
int convert(char barcode[], int n, char code[]);
int match(char a[], int aStart, char b[], int bStart, int n);

int main()
{
FILE* fp;
fp = fopen(".\\barcode.dat", "r");
while (NULL == fp)
{
fp = fopen(".\\barcode.dat", "r");
//Sleep(1);
}


char barcode[95] = {0};
int upc[12] = {0};
int ch;
int i=0;
ch = fgetc(fp);
while (i <95 && feof(fp) == 0)
{
barcode[i] = (char)ch;
ch = fgetc(fp);
i++;
}

//省打印相应左右值

analyze(barcode, upc);
for (i=0; i <12; i++)
{
printf("%d",upc[i]);
}
printf("\n");
printf("OK");
getchar();

return 1;
}

void analyze(char barcode[], int upc[])
{
int i,j,start=3;

for (i=0; i <6; i++)
{
for (j=0; j <10; j++)
{
if(convert(barcode, start, left[j].code))
{
upc[i] = j;
break;
}
}
start += 7;
}

start += 5;

for (; i <12; i++)
{
for (j=0; j <10; j++)
{
if(convert(barcode, start, right[j].code))
{
upc[i] = j;
break;
}
}
start += 7;
}
}

int convert(char barcode[], int n, char code[])
{
if (match(barcode, n, code, 0, 7))
{
return 1;
}
return 0;
}

int match(char a[], int aStart, char b[], int bStart, int n)
{
int i, nRet=0;
for (i=0; i <n; i++)
{
if (a[aStart] == b[bStart])
{
aStart++;
bStart++;
nRet++;
}
else
{
break;
}
}

return (nRet == n) ? 1 : 0;
}



注释暂时没写...

热点排行