1.考虑查找给定输入单词的所有变位词问题。我们只需在问题C进行更改存储方式即可
程序如下,用一个 HashMap<String, ArrayList<String>>(C++可用map<string,vector<stirng>> 来存储)
来保存结果即可,键为标识,值为同位词构成的list
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
class WordInfo{
public String word="";
public String flag="";
}
public class tC {
public static HashMap<String, ArrayList<String>> result=new HashMap<String, ArrayList<String>>();
public static void computeFlag(WordInfo wordInfo){
String word=wordInfo.word;
char[] flag=word.toCharArray();
Arrays.sort(flag);
System.out.print(wordInfo.word);
// 方案一: for(int index=0;index<flag.length;index++){
// wordInfo.flag+=flag[index];
// }
int count,index;
for(index=0;index<flag.length;index++){
count=1;
while( (index+1<flag.length) && ( flag[index]==flag[index+1] )){
count++;
index++;
}
wordInfo.flag+=flag[index];
if(count>1){
wordInfo.flag+=count;
}
}
System.out.println(" "+wordInfo.flag);
ArrayList<String> sameSpellWord=result.get(wordInfo.flag);
if(sameSpellWord==null){
sameSpellWord=new ArrayList<String>();
sameSpellWord.add(wordInfo.word);
result.put(wordInfo.flag,sameSpellWord);
}
else{
sameSpellWord.add(wordInfo.word);
// result.put(wordInfo.flag,sameSpellWord);
}
}
public static void main(String args[]){
WordInfo wordsInfo[]=new WordInfo[10];
String words[]={"tops","stop","pots","posited","deposit","posited","topside","cholecystoduodenostomy","duodenocholecystostomy","rubber"};
for(int i=0;i<10;i++){
wordsInfo[i]=new WordInfo();
wordsInfo[i].word=words[i];
computeFlag(wordsInfo[i]);
}
// for(int i=0;i<10;i++){
// System.out.println(wordsInfo[i].word+" 的同位词有: ");
// for(int j=0;j<10;j++){
// if(i!=j&&wordsInfo[i].flag.equalsIgnoreCase(wordsInfo[j].flag)){
// System.out.print(wordsInfo[j].word+"\t");
// }
// }
// System.out.println();
// }
System.out.println(result);
}
}
2.给定一个包含4300 000 000个32位整数的顺序文件,如何找出一个出现至少两次的整数。
直接上代码,然后进行解释。
#include <iostream>
#include <math.h>
using namespace std;
/* a, b, c,都是三个等长的数组,
a数组用来保存要探测的所有的值
b数组用来保存当前bit位为1的数
c数组用来保存当前bit为为0的数
aLen表示a数组的其长度。
bit表示开始从哪一位测试,当然首先从最高位开始,然后递减。
比如32位。bit=32.(以测试数据中的最大数的最高位为准,如最大数为15(1111)则取4,若最大数为30(11110)则取5
*/
void printArr(int a[],int length){
for(int i=0;i<length;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}
int get_same(int *a, int *b, int *c, int aLen, int bit)
{
int theSameNumber=0, flag= 0, bLen = 0, cLen, i = 0;
int shouldHaveAmounts=pow(2,bit);
//flag用来与数值进行与操作,来对数值进行分类;bLen用来表示b数组长度,cLen用来表示c数组长度
while (bit--)
{
flag = (1 << bit);
for (bLen = cLen = i = 0; i < aLen&&bLen<(shouldHaveAmounts/2+1)&&cLen<(shouldHaveAmounts/2+1); ++i)
//每进行一次循环就判断,当前是否有子数组的长度超过应有长度的一半,超过就退出
{
if (a[i] & (flag)) b[bLen++] = a[i]; //当a[i]当前bit位为1时存入b数组
else c[cLen++] = a[i]; //当a[i]当前bit位为0时存入c数组
}
if (bLen>cLen) //找到分出来的更长的数组,此时表示b数组更长,
{
theSameNumber += flag; //当为b数组时加上对应的高位为1的换算值(1<<bit)
a = b;
aLen = bLen;
printArr(a,aLen);
}
else
{
a=c;
aLen = cLen;
printArr(a,aLen);
}
shouldHaveAmounts/=2;
}
return theSameNumber;
}
int main(){
int originalArr[17]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,14,15};
int category1[17];
int category0[17];
int theSameNumber=get_same(originalArr,category1,category0,17,4);
cout<<theSameNumber;
}
此程序,可以在问题A的问题上稍作修改即可得到。
如上述程序的测试数据,假设现在的最高位为第四位,2的4次方为16,所有理应至多有16个数才不会导致数值重复,而所给数据为<=15的17个数,那么此时必定存在重复出现的数值。我们判断数值的当前最高位,若为1,则分入b数组;若为0,则分入c数组,与此同时不断检测b数组或是c数组的长度是否存在超过应有数目的一半,若超过则退出循环;然后测试下一位,将应有数目减半,重复上述的分类行为;最终bit为-1跳出循环得到值。
3.杂耍向量旋转算法: 更改了变量的名称方便理解点,也做了输入测试
#include<iostream>
#include<math.h>
#define arrayLength 10
using namespace std;
char x[arrayLength]="adeghcesh";
int gcd(int bigger,int smaller){
int rest=bigger%smaller;
while(rest>0){
bigger=smaller;
smaller=rest;
rest=bigger%smaller;
}
return smaller;
}
void printArr(int charArrLength){
for(int i=0;i<charArrLength;i++){
cout<<x[i]<<" ";
}
cout<<endl;
}
void playSwap(int leftMoveLength,int charArrLength){
for(int i_moveStart=0;i_moveStart<gcd(leftMoveLength,charArrLength);i_moveStart++){
//找到需要以哪个元素作为开始进行移动覆盖,i_moveStart表示第一个需要被覆盖元素的下标
char temp=x[i_moveStart];
int i_beOverrided=i_moveStart;//i_beOverrided需要被覆盖的下标
while(true){
int i_doOverride=i_beOverrided+leftMoveLength;
if(i_doOverride>=charArrLength)
i_doOverride-=charArrLength;
if(i_doOverride==i_moveStart)
break;
x[i_beOverrided]=x[i_doOverride];
printArr(charArrLength);
i_beOverrided=i_doOverride;
}
x[i_beOverrided]=temp;
printArr(charArrLength);
}
printArr(charArrLength);
}
int main(){
playSwap(3,arrayLength-1);
}
4.略过,性能测试喜欢的可用自己试试