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

关于华为机试题求代码!该怎么处理

2012-04-23 
关于华为机试题求代码!!!n个字符串,1n20找出n个字符串中相同的最长的子字符串;如n31.what is local bu

关于华为机试题求代码!!!
n个字符串,1<n<20;找出n个字符串中相同的最长的子字符串;
如n=3
1.what is local bus?
2.this is local bus。
3.local bus is name sdhfj。
那么最长的共同子串是local bus
函数为char * findchar(const char**asd,const int n)
大体就是这些,用c去实现!!
大牛们 给力啊!!

[解决办法]
这样:先比较两个字符串, 找出所有互不包含的公共子串。
然后这堆子串再与第三个字符串相比,找出新的公共字串,,,
最后选出最长的那个。
[解决办法]
先两个字符串找 公共子串 。
然后拿公共子串和下一个字符串找 公共子串
往复循环,最后剩下的 公共子串 中找最长的 子串 返回。
最后没有剩下公共子串则返回NULL。

个人想法,估计这个贴会火,来顶一个..
[解决办法]
1、计算出 n 个字符串中最短的字符串a 的长度l, pos=0,len=l/2, n=1
2、从字符串a 的pos 位置取长度len 个字节
3、判断步骤2中的字节是否在其他n-1个字符串中
4、是,判断l/2^n是否为0,是,结束;否,len+=l/2^n,n++,回步骤2
5、否,判断pos>l-len,是,len-=l/2^n,n++,pos=0,回步骤2;否,pos++,回步骤2
6、从字符串a 的pos 位置取长度len 个字节作为返回值
[解决办法]
既然每个字符串都包含最长子字符串
1\选择 第1个和第2个字符串得到 最长子字符串a
2\选择 第3个和第4个字符串得到 最长子字符串b
3\从a b中得到最大子字符串c

4\选择 第5个和第6个字符串得到 最长子字符串d
5\选择 第7个和第8个字符串得到 最长子字符串e
6\从d e中得到最大子字符串f

从c f中得到子字符串。。。。g

。。。。。。。。。。。。。。。。。。。。。
[解决办法]

探讨

引用:

先两个字符串找 公共子串 。
然后拿公共子串和下一个字符串找 公共子串
往复循环,最后剩下的 公共子串 中找最长的 子串 返回。
最后没有剩下公共子串则返回NULL。

个人想法,估计这个贴会火,来顶一个..

顶,只要写出针对两个串求最长公共串的代码,剩下就是循环的问题了,当然,可能有出现有多个一样长的公共串的情况,处理应该也不太复杂。

[解决办法]
手上只有一个Python版的,LZ自己改成C++吧

values = [1,-2,3,10,-4,7,2,-5]
def getMaxSum(values):
maxSum = 0
sum = 0
maxNegativeNum = values[0]

if not values:
return None

for value in values:
sum = sum + value
if maxNegativeNum < value < 0:
maxNegativeNum = value
if sum < 0:
sum = 0 
if sum > maxSum:
maxSum = sum 

if sum == 0:
return maxNegativeNum

return maxSum

[解决办法]
C/C++ code
#include <iostream>#include <string>using namespace std;//将第一个字符串与最短的字符串交换void swap(string *pStr,int i){    string temp;    temp = *pStr;    *pStr = *(pStr + i);    *(pStr + i) = temp;}int main(){    int N = 3;        //cout << "请输入N(控制字符串个数):";    //cin >> N;    //cout << "请输入" << N << "个字符串"<<endl;    string *pStr;    pStr = new string [N];//记录要查找的字符串    pStr[0] = "main what is local bus";    pStr[1] = "main this is local bus";    //pStr[2] = "local bus is name sdhfj";    pStr[2]  = "main";    int i,min;    int maxLen = 256;    //找出输入的字符串中长度最小的串,并把最小串序号记在min中    for(i = 0; i < N; ++i){       // cin >> *(pStr + i);        int len = (*(pStr +i)).length();// *操作符与调用函数的.操作符优先级问题,.优先级高于*,所以必须加上()        if(len < maxLen){            maxLen = len;            min = i;        }    }    swap(pStr,min);    /*    for(i = 0; i < N; ++i)        cout << *(pStr + i) << endl;    */        int len0 = pStr[0].length();    int j,k,maxlen= 0;    string maxStr;    string tmpStr;    for(i = 0; i < len0 && maxlen <= len0 - i -1; ++i)    {        for(j = 0; j < len0 && maxlen <= len0 - i -j - 1; ++j)        {            tmpStr = pStr[0].substr(i,len0 - j);//对字符串数组中第一个子串,求出其可能的子串值,如果剩余子串长度小于maxlen则不用去求了,for循环中给出了限制            //将子串tmpStr与参与匹配的字符串比较,判断tmpStr是否为剩余串的子串,如果不是则break出循环            for(k = 1; k < N; ++k)            {                string::size_type pos1 = pStr[k].find(tmpStr);                if(pos1 < pStr[k].length())                    continue;                else                    break;            }            if(k == N)//说明子串tmpStr是其他参与匹配的子串的子串            {                if(tmpStr.length() > maxlen)//tmpStr如果是当前最大的子串,则记录下来                {                    maxlen = tmpStr.length();                    maxStr = tmpStr;                }            }        }    }    cout << "最大公共子串为:";    cout << maxStr <<endl;    delete []pStr;    return 0;} 


[解决办法]
#include<string.h>
#include<stdio.h>
#include <stdlib.h>
#define M 100

char* LCS(char left[],char right[])

{ //LCS问题就是求两个字符串最长公共子串的问题

int lenLeft=strlen(left),lenRight=strlen(right),k;

//获取左子串的长度,获取右子串的长度

char *c=(char*)malloc(lenRight),*p;//注意这里要写成char型,而不是int型,否则输入整型数据时会产生错误。 //矩阵c纪录两串的匹配情况

//int c[M][M]={0};//当将c申明为一个二维数组时

int start,end,len,i,j;//start表明最长公共子串的起始点,end表明最长公共子串的终止点

end=len=0;//len表示最长公共子串的长度

for(i=0;i<lenLeft;i++)//串1从前向后比较

{ for(j=lenRight-1;j>=0;j--)//串2从后向前比较,为什么要从后向前呢?是把一维数组c[ ]当二维数组来用,
//如果要从前向后,可以将c申明为一个二维数组c[M][M].但程序要做相应调整.

// for(j=0;j<lenRight;j++)//当c申明为一个二维数组时

{ if(left[i] == right[j])//元素相等时

{ if(i==0||j==0)

c[j]=1;//c[i][j]=1;

else

{ c[j]=c[j-1]+1;//c[i][j]=c[i-1][j-1]+1;

}

}

else

c[j] = 0;//c[i][j]=0;

if(c[j] > len)//if (c[i][j]>len)

{ len=c[j];//len=c[i][j];

end=j;

}

}

}

start=end-len+1;

p =(char*)malloc(len+1);//数组p纪录最长公共子串

for(i=start; i<=end;i++)

{ p[i-start] = right[i];

}

p[len]='\0';

return p;

}

void main()

{ char str1[M],str2[M],str3[M];

printf("请输入字符串1:");

gets(str1);

printf("请输入字符串2:");

gets(str2);

 // printf("请输入字符串3:");

 // gets(str3);

printf("最长子串为:");

printf("%s\n",LCS(str1,str2));

//char *p=LCS(str1,str2);

// printf("%s\n",LCS(p,str3));

}
这是求两个字符串的最长相同子串,用的是一个二维矩阵的思想,求三个字符串的最长相同子串我觉得可以用三维数组了
[解决办法]
#include <iostream>
#include <string>

using namespace std;

//将第一个字符串与最短的字符串交换
void swap(string *pStr,int i)
{
string temp;
temp = *pStr;
*pStr = *(pStr + i);
*(pStr + i) = temp;
}

int main()
{
int N;

cout << "请输入N(控制字符串个数):";
cin >> N;

cout << "请输入" << N << "个字符串"<<endl;

string *pStr;
pStr = new string [N];
int i,min;
int maxLen = 1000;
//找出输入的字符串中长度最小的串,并把最小串序号记在min中
for(i = 0; i < N; ++i){
cin >> *(pStr + i);
int len = (*(pStr +i)).length();// *操作符与调用函数的.操作符优先级问题,.优先级高于*,所以必须加上()
if(len < maxLen){
maxLen = len;
min = i;
}
}
swap(pStr,min);
/*
for(i = 0; i < N; ++i)
cout << *(pStr + i) << endl;
*/

int len0 = pStr[0].length();
int j,k,maxlen= 0;
string maxStr;
string tmpStr;
for(i = 0; i < len0 && maxlen <= len0 - i -1; ++i)
{
for(j = 0; j < len0 && maxlen <= len0 - i -j - 1; ++j)
{
tmpStr = pStr[0].substr(i,len0 - j);//对字符串数组中第一个子串,求出其可能的子串值,如果剩余子串长度小于maxlen则不用去求了,for循环中给出了限制
//将子串tmpStr与参与匹配的字符串比较,判断tmpStr是否为剩余串的子串,如果不是则break出循环
for(k = 1; k < N; ++k)
{
string::size_type pos1 = pStr[k].find(tmpStr);
if(pos1 < pStr[k].length())


continue;
else
break;
}
if(k == N)//说明子串tmpStr是其他参与匹配的子串的子串
{
if(tmpStr.length() > maxlen)//tmpStr如果是当前最大的子串,则记录下来
{
maxlen = tmpStr.length();
maxStr = tmpStr;
}
}
}
}
cout << "最大公共子串为:";
cout << maxStr <<endl;
delete []pStr;
return 0;
}

探讨

引用:
C/C++ code

#include <iostream>
#include <string>

using namespace std;

//将第一个字符串与最短的字符串交换
void swap(string *pStr,int i)
{
string temp;
temp = *pStr;
*pStr = *(pStr + i);
……

[解决办法]
这题比较简单(当然当场作出来难度还是比较大的),给你们看一道难度更大的题。这一题中的子串可以是非“连续”的。
Longest Common Subsequence



Challenge Description
You are given two sequences. Write a program to determine the longest common subsequence between the two strings(each string can have a maximum length of 50 characters). (NOTE: This subsequence need not be contiguous. The input file may contain empty lines, these need to be ignored.)


Input
The first argument will be a file that contains two strings per line, semicolon delimited. You can assume that there is only one unique subsequence per test case. e.g. 

XMJYAUZ;MZJAWXU

Output
The longest common subsequence. Ensure that there are no trailing empty spaces on each line you print. e.g. 

MJAU



[解决办法]
可以用后缀数组求出所有n个串中最短的两个的公共子串。剩下的就是集合求交的问题了,就是在其他的子串中查找该公共子串的集合。如果有一个不含所有的子串,那么直接返回空。
[解决办法]
1.通过二维矩阵找出任意两个字符串的所有公共子串


2.将找出的所有公共子串一一跟剩下的字符串匹配,看看其中有没有。
[解决办法]
这个是最长公共子序列问题,一般使用动态规划处理。
汗~面试一般也就求个2个序列最长的吧。

参考:http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
中文的:http://zh.wikipedia.org/wiki/%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97
[解决办法]
还有参考:算法导论 中文第二版 第208页 15.4节 最长公共子序列。
关注习题15.4-6 是优化后的O(nlgn)算法。
[解决办法]
估计你还是个学生吧,人家给出了要求的函数原型,要求的是入参是个二维指针,这个二维指针是要求传进N个字符串的,要是你去机试直接过不了。。。更不要说你的实现效率很低。。。
探讨

C/C++ code
#include <iostream>
#include <string>

using namespace std;

//将第一个字符串与最短的字符串交换
void swap(string *pStr,int i)
{
string temp;
temp = *pStr;
*pStr = *(pStr + i);
*(pStr + i)……

[解决办法]
发现好多人比较两个字符串是都只考虑找最长的子序列。但是假如两个字符串中存在好几个一样长的都是最长的子序列呢?
另外题目给出的函数原型char * findchar(const char**asd,const int n)
要求返回一个字符串指针,这个内存不能由系统栈分配,又要自己进行堆内存分配的管理;
其次是这个const char**asd, lz没看错么?应该是char** const asd吧?
[解决办法]
这个算法效率有点低,但暂时只能想出这个了……
C/C++ code
#include <iostream>#include <string>#include <vector>using namespace std;void find(const string &str1, const string &str2,  vector<string> &result){    typedef vector<string>::size_type size_t;    typedef vector<string>::difference_type diff_t;    result.clear();    size_t length = 0;    const size_t length1=str1.length(),                 length2=str2.length();    for (size_t pos1=0; length1!=pos1; ++pos1) {        for (size_t pos2=0; length2!=pos2; ++pos2) {            diff_t diff=0;            for (;                 pos1+diff != length1 &&                  pos2+diff != length2 &&                 str1[pos1+diff] == str2[pos2+diff];                 ++diff) ;            if (length < diff) {                length = diff;                result.clear();                result.push_back( str1.substr(pos1,diff) );            } else if (length == diff) {                length = diff;                result.push_back( str1.substr(pos1,diff) );            }        }    }}void findchar (char ** const asd, const size_t n){    if (n<1) return;    if (n<2) {        cout << asd[0] << endl;        return;    }    vector<string> result;    find(asd[0], asd[1], result);    typedef vector<string>::const_iterator const_iter;    for (size_t i=2; i!=n; ++i) {                vector<string> list(result);        for (const_iter beg=list.begin(), end=list.end();             beg != end;             ++beg) {            find(asd[i],*beg, result);        }    }    for (const_iter beg=result.begin(), end=result.end();         beg != end;         ++beg) {        cout << *beg << endl;    }}int main(){    char *asd[3];    char result[256];    char *str0="what is local bus?";    char *str1="this is local bus.";    char *str2="local bus is name sdhfj.";    asd[0] = str0;    asd[1] = str1;    asd[2] = str2;    findchar (asd, 3);    return 0;} 

热点排行