問題A:給定一個最多包含40億個隨機排列的32位的順序文件,找到一個不在文件的32位整數。在內存足夠的情況下,如何解決該問題?如果有幾個外部的臨時文件可以用,但是僅有幾百個字節可以用,又該如何解決問題
當內存夠的情況下,C/C++可以用set集合來做,同樣的Java可以用HashSet來做,或者使用第一章的位圖法用1個int來存儲32個數,0表示不存在,1表示存在。。具體就不說了
下面是不夠的源碼
#include <iostream>
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
*/
int get_lost(int *a, int *b, int *c, int aLen, int bit)
{
int theLostNumber = 0, flag= 0, bLen = 0, cLen, i = 0;
//flag用來與數值進行與操作,來對數值進行分類;bLen用來表示b數組長度,cLen用來表示c數組長度
while (bit--)
{
flag = (1 << bit);
for (bLen = cLen = i = 0; i < aLen; ++i)
{
if (a[i] & (1 << bit)) b[bLen++] = a[i]; //當a[i]當前bit位爲1時存入b數組
else c[cLen++] = a[i]; //當a[i]當前bit位爲0時存入c數組
}
if (bLen <= cLen) //找到分出來的更短的數組,此時表示b數組更短,
{
theLostNumber += flag; //當爲b數組時加上對應的高位爲1的換算值(1<<bit)
a = b;
aLen = bLen;
}
else
{
a=c;
aLen = cLen;
}
}
return theLostNumber;
}
int main(){
int originalArr[14]={1,2,3,4,5,6,7,8,9,10,11,12,13,15};
int category1[14];
int category0[14];
int theLostNumber=get_lost(originalArr,category1,category0,14,4);
cout<<theLostNumber;
}
問題B:字符串循環移位
算法思想來源於書上
啊哈靈機一動:我們將問題看成是數組ab轉換成爲數組ba。
實現原理(或者說是數學原理)
先對a求逆,得到a’b;再對b求逆,得到a’b’;最後對a’b’求逆,得到ba
#include<iostream>
#define Length 9
using namespace std;
char array[Length]="abcdefgh";
void reverse(int start,int end){
int increment;
char temp;
int middle=(start+end)/2;
for(increment=0;increment+start<=middle;increment++){
temp=array[increment+start];
array[increment+start]=array[end-increment];
array[end-increment]=temp;
}
}
int main(){
cout<<"對前三個求逆\n";
reverse(0,2);
for(int i=0;i<Length-1;i++){
cout<<array[i];
}
cout<<endl;
cout<<"對剩下的求逆\n";
reverse(3,Length-2);
for(int i=0;i<Length-1;i++){
cout<<array[i];
}
cout<<endl;
cout<<"對所有的求逆\n";
reverse(0,Length-2);
for(int i=0;i<Length-1;i++){
cout<<array[i];
}
}
**題C:給定一個英文字典,找到其中的所有變位詞集合。列如,”pots”,”stop”,和”tops”互爲變換詞。因爲
每一個單詞都可以通過其他單詞變換字母順序得到,也就是每一個單詞都由相同字母,且相應字母個數都相等的字母集構成。**
package chapter2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.TreeSet;
class WordInfo{
public String word="";
public String flag="";
}
public class tC {
public static HashMap<String, TreeSet<String>> result=new HashMap<String, TreeSet<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);
TreeSet<String> sameSpellWord=result.get(wordInfo.flag);
if(sameSpellWord==null){
sameSpellWord=new TreeSet<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);
}
}