1. 程式人生 > >輸出兩字串最大相同部分——C面試題

輸出兩字串最大相同部分——C面試題

面試題,是紙上寫的,發現了些錯誤,回來改進了下。寫紙上和寫計算機裡並編譯成功完全是兩個效果。

開始沒太多字串操作,很繁瑣、難點也多,後逐漸改進

典型問題1:

sizeof()侷限於棧陣列

char a[] = "asd213123123";

形式,並且這種不能用'\0'判斷是否結束(這種判斷方式能很方便加在while條件中用於判斷越界——b != '\0')。

如果是字串常量:

char *b = "dasadafasdf";

這種情況,sizeof()就廢掉了!

總之:

對號入座,前者sizeof、後者strlen~!不過sizeof(a)和strlen(b)還有另外一個區別,strlen不計算'\0',而sizeof要計算(前提是sizeof()不針對char指標)

典型問題2:

用什麼來暫存並輸出結果?還是隻是記錄下來相關位置——這是我底下未完成版本1想到的思路——用一個count[sizeof(A)]陣列記錄下A每個位置作為起點所能和B達到的最大重合,最後判斷查詢陣列中最大值,此時目標子字串的起點下標(i)和 i 對應的長度(counter[i])都有了。

這是針對不知道字串大小並且不佔用額外空間的做法,需要非常繁瑣的操作,要加很多標記,越界判斷也會有些麻煩(結合優勢麼,用字串常量而不是棧空間中的字元陣列,有'\0'——就好判斷了!)

(關於空間的佔用,如果要用一個和字串a一樣長的陣列counter來計錄a中各起點對應與b最大重合子字串,這個陣列也要和a一樣長,空間上也不合適,除非情形很特殊,a短b長,不然不如直接malloc()一個堆空間來儲存當前最長“子字串”,並實時更新)


先放一個改完編譯測試成功的。

release1

//題目:要求比較A字串(例如“abcdef"),B字串(例如(bdcda)。找出重合度最大的子字串,輸出(根據OJ經驗,輸>出結果對即可)
#include<stdio.h>
#include<string.h>
#include<malloc.h>
main(){
        char *A = "abcderfghi";
        char *B = "aderkkkkkabcd";

        int i,j,c = 0,count = 0;
        unsigned int maxSeg = 0;

        int max = strlen(A) > strlen(B) ? strlen(A) : strlen(B);
        char* final = (char*)malloc(sizeof(char) * (max + 1));
        final[max] = '\0';
        for(i = 0;A[i] != '\0';i++){
                for(j = 0;B[j] != '\0';j++){
                        while(A[i + c] == B[j] && A[i+c] != '\0' && B[j] != '\0'){
                                count++;
                                c++;
                                j++;
                        }
                        if(count > maxSeg){
                                strncpy(final,(A + i),count);
                                maxSeg = count;
                        }
                        count = 0;
                        c = 0;
                }
        }
        printf("%s\n",final);
        free(final);

}

這是能將就用的第一個版本~!關於結束符'\0'能否影響free()的使用,覺得是完全不用操心的,因為malloc的大小是系統來儲存的,刪除時候系統來接手就完了,而'\0'結束符只是針對一些常規字串操作,比如printf()用%s控制輸出時~!

新難點:找到的子字元串同時一樣長怎麼辦?那我這隻能叫做”第一個最長的重合字串“用兩塊空間來儲存?三段等長怎麼辦?
如:

"abclbcdlcdel"

"kabckbcdkcde"

abc長3,bcd長3,cde長3。。。

未完成版本1:這段是錯誤示範,初期定位模糊思路亂,有些函式和功能不把握,又在紙上寫。

思路亂的一個後果就是前期想用i和j簡單判斷越界問題,後期又弄了i+c之類的下標,

修改思路:

把字串換成“字串常量”——帶'\0'的,這樣在小while中用 != '\0'就能判斷出界問題。

把字串變成字串常量以後的另一個問題是sizeof不能用了,引入string.h,用strlen()替代即可。

//題目:要求比較A字串(例如“abcdef"),B字串(例如(bdcda)。找出重合度最大的子字串,輸出(根據OJ經驗,輸出結果對即可)

//遺忘,未使用string.h相關函式。
#include<stdio.h>
main(){
	char A[] = "asdasd";
	char B[] = "asdasd";
	/*本版本處理方式為最通用的針對字串大小未知情況的遍歷——比如“字串常量”——此時可用strlen()代替sizeof(),並引入<string.h>即可。
	*但是因在紙上做題,在條件上做了簡化————使用了sizeof()可確定大小的字元陣列而非“字串常量”。具體用sizeof()還是strlen()。這些小問題請讀者自行區分。
	*如果可用sizeof()確定大小,就可以用malloc()建立一個臨時字串來儲存並輸出最大字元子段,程式碼會簡化很多~!
	*不過如果用malloc()儲存最大子段,隨著最大子段變化,需要不停的free()再重新malloc(),要注意
	*/
	int i,j,flag,c = 0,temp = 0,max = 0,count[sizeof(A)];
	for(i = 0;i < sizeof(A);i++){//以i為A中“子字串”首位,遍歷B,看B中與A[i]起的子字串最大匹配數量是多少,記為count[i],每個count[i]對應A中一個字元
		for(j = 0;j < sizeof(B);j++){
			while(A[i + c] == B[j]){//準備了一個c做偏移,免得更改i會變亂
				temp++;
				c++;
				j++
				if(temp > count[i])//找出B中匹配度最高子段,不用記錄下標,只需記錄匹配的字元數量,A[i]是固定的起點,加上偏移量,就是這段
					count[i] = temp;
			}
			//清零,準備面對新的起點j~!以j為起點再找匹配的一段字串
			//j不用恢復~!恢復原樣的話,算上j++是移動了一位,不會死迴圈~!但是,因為這一段本來就是連續的,abcd都連續了,bcd和cd不用看了。
			temp = 0;
			c = 0;
		}
	}
	//比較count陣列,看哪個i對應子段越大
	//temp = 0;//節省空間的考慮(雖然只有4B),怕不適應就改叫max,去宣告一個max變數。
	for(i = 0;i < sizeof(A);i++)
		if(count[i] > max){//找出最大的一個計數器~~~~並記錄i!!!
			max = count[i];//這句可以精簡掉,可能?不可以,作為“下標”可以被精簡,因為有了flag~!但作為max不能少,做比較用——叫max比較好理解。
			flag = i;//用flag記錄相應最大子段的起始偏移量
		}
	
	//輸出該子段
	for(i = flag;i < flag + count[flag];i++){//temp來源於前一個for迴圈,意為最大偏移量。
		printf("%c",A[i]);
	}
	printf("\n");

}


相關推薦

輸出字串相同部分——C試題

面試題,是紙上寫的,發現了些錯誤,回來改進了下。寫紙上和寫計算機裡並編譯成功完全是兩個效果。 開始沒太多字串操作,很繁瑣、難點也多,後逐漸改進。 典型問題1: sizeof()侷限於棧陣列 char a[] = "asd213123123"; 形式,並且這種不能用'\0'

求出值的C程式

1.不使用判斷語句 #include <stdio.h> #include <math.h> double Max(double a, double b) { double q = sqrt((a-b)*(a-b)); return

【動態規劃】LCS演算法:求字串公共字串(連續)

LCS演算法的應用 問題描述:求兩字串的連續最大公共子字串 思路:根據上文LCS演算法求解兩字串的最大公共子序列(不連續),可以得到求解連續子字串的啟示,如圖所示,構造LCS矩陣vec,將兩個字串按矩

字串相同的子串

求得短的字串和長的字串兩個字串中相同的字串段。    public static String getMaxSubString(String s1, String s2) {         String

求任意字串相同子串

c語言# include<stdio.h> #include<string.h> int main(){ char a[100],b[100]; printf("s1="); scanf("%s",a); printf("s2="); s

編寫程式,獲取字串相同子串

private void test() { String a = "Valaienie"; String b = "Maierginle"; String max = a.length() > b.length() ? a : b; String min =

String包裝類應用之 獲取字串相同子串

exa: 1.獲取兩個字串中最大相同子串。比如: str1 = “abcwerthelloyuiodef”; str2 = “cvhellobnm” 提示:將短的那個串進行長度依次遞增的子串與

用javascript求字串相同的子串

思路: 1.找出兩個字串的最大和最小字串(根據長度)。 2.從最小的字串中先取該字串的長度的子串,判斷大的字串中是否包含該子串,不包含將長度減1,從小的字串中取該長度的子串再去判斷,如此反覆。 &

字串尋找相同子串

1.s1.contains(sub)  存在返回true2.把較短字串先與長的contains,存在則輸出;不存在則減一再containspublic class StringTest_3 {public static void main(String[] args) {St

ACMNO.3 有三個整數a b c,由鍵盤輸入,輸出其中的的數。 輸入 一行陣列,分別為a b c 輸出 a b c其中的數 樣例輸入 10 20 30 樣例輸出 30

基於平臺Dev-C++ 5.11 題目描述 有三個整數a b c,由鍵盤輸入,輸出其中的最大的數。 輸入 一行陣列,分別為a b c 輸出 a b c其中最大的數 樣例輸入 10 20 30 樣例輸出 30 提示 max ? if(a

C語言實現求個數的值,C語言實現雞兔同籠問題

實驗三:輸入兩個數求最大者 #include<stdio.h> int main()//主函式 { int max(int x,int y); int a,b,c; printf("請輸入a:\n"); scanf("%d",&a); pr

求一個字串的字首與另一個字串的字尾的相同子串

求字串ptr的字首與str的字尾的最大相同子串,若不存在,輸出0。 樣例輸入 mike aniom kiava dvakia dasds fdsgh 樣例輸出 m 1 kia 3 0 分析: 先求字串ptr的next陣列,然後使用KMP演算法求ptr的字首與str字尾的最

LeetCode系列字串操作(一)ZigZag輸出,尋找不重複字串長度。

ZigZag Conversion The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to d

java實現字串公共子字串

/** * @author weichen CHEN created on 2018/4/20 * @version 2018/4/20 weichen CHEN */ public class Test { public static void main

字串是否存在相同部分的比較

需求:使用者名稱同密碼不能存在區域性相同。例如 username:wangxiaoming password:xiaoming123 監測到存在相同的字串‘xiaoming’,則不允許。

字串長公共連續子串---C++程式設計

題目:有兩個字串(可能包含空格),找出其中最長的公共連續子串,並輸出其長度。  輸入描述:輸入為兩行字串(可能包含空格),長度均小於等於50。 輸出描述:  輸出為一個整數,表示最長公共連續子串的

輸出字串中第二個字串的不同部分

def func(x): d={} for i in range(len(x)): d[i] = x[i] return d if __name__ == "__main__": A = "qqqq"

核心API的使用(獲取個字符串的相同子串)

ins for system bst span sam sub string 三目運算 /** * 獲取兩個字符串的最大相同子串。 例:abegad acegab */public class TheSameString { public static void main(

輸入一組整數,0結束輸入,之後輸出輸入的的和小的整數.【思路】

cnblogs amp println system ack rgs int 輸入 != package com.ykmimi.new1; /** * 輸入一組整數,0結束輸入,之後輸出輸入的最大的和最小的整數. */ import java.util.Scanner

【劍指offer】滑動窗口的值,C++實現

AD png lock -a https 大小 idt style 可能 原創博文,轉載請註明出處! # 題目 # 思路 利用C++中的雙端隊列保存有可能是滑動窗口最大值的下標,其中隊首元素保存當前窗口最大值的下標。當滑動窗口改變時,更新隊列。隊列更新的規則: