最短字元編碼

2021-08-26 02:26:26 字數 2847 閱讀 1521

給定乙個非空字串, 按照如下方式編碼, 使得編碼後長度最小, 返回編碼後的長度: 

編碼規則為: k[encoding_string], 表示重複k次encoding_strng, 

例如'abcdefabcdefabc'可表示為'2[abcdef]abc', 但是'aaa'僅能編碼成'aaa', 

因為len('3[a]')>len('aaa').

補充:1. k為正整數, 內的encoding_string不得含有空格不得為空;

2. 內的encoding_string 本身可以為編碼過的字串, 例如'abcdabcdeabcdabcde' 可以編碼為 '2[abcdabcde]'(編碼後長度從18減少到12), 內的'abcdabcde'又可以編碼為 '2[abcd]e', 最終編碼為 '2[2[abcd]e]', 編碼後長度為11, 應返回11; 這個編碼路徑也能是: 'abcdabcdeabcdabcde' -> '2[abcd]e2[abcd]e' -> '2[2[abcd]e]';

2. 輸入字串為全小寫英文本母, 長度<=160;

3. 如果編碼後長度沒有更小, 則保留原有字串;

輸入描述:

一行資料, 表示輸入字串
輸出描述:

輸出乙個字串表示編碼後長度
輸入例子1:

aaa
輸出例子1:

3
例子說明1:

aaa,長度3
輸入例子2:

aaaaa
輸出例子2:

4
例子說明2:

5[a],長度4
輸入例子3:

aabcaabcd
輸出例子3:

8
例子說明3:

2[aabc]d,長度8
解題思路:我們建立乙個二維的dp陣列,其中dp[i][j]表示s在[i, j]範圍內的字串的縮寫形式(如果縮寫形式長度大於子字串,那麼還是保留子字串),那麼如果s字串的長度是n,最終我們需要的結果就儲存在dp[0][n-1]中,然後我們需要遍歷s的所有子字串,對於任意一段子字串[i, j],我們我們以中間任意位置k來拆分成兩段,比較dp[i][k]加上dp[k+1][j]的總長度和dp[i][j]的長度,將長度較小的字串賦給dp[i][j],然後我們要做的就是在s中取出[i, j]範圍內的子字串t進行合併。合併的方法是我們在取出的字串t後面再加上乙個t,然後在這裡面尋找子字串t的第二個起始位置,如果第二個起始位置小於t的長度的話,說明t包含重複字串,舉個例子吧,比如 t = "abab", 那麼t+t = "abababab",我們在裡面找第二個t出現的位置為2,小於t的長度4,說明t中有重複出現,重複的個數為t.size()/pos = 2個,那麼我們就要把重複的地方放入中括號中,注意中括號裡不能直接放這個子字串,而是應該從dp中取出對應位置的字串,因為重複的部分有可能已經寫成縮寫形式了,比如題目中的例子5。如果t = "abc",那麼t+t = "abcabc",我們在裡面找第二個t出現的位置為3,等於t的長度3,說明t中沒有重複出現,那麼replace就還是t。然後我們比較我們得到的replace和dp[i][j]中的字串長度,把長度較小的賦給dp[i][j]即可,時間複雜度為o(n3),空間複雜度為o(n2)

**如下:

#include

#include

#include

using namespace std;

string encode(string s)

}string t = s.substr(i, j - i + 1), replace = "";

auto pos = (t + t).find(t, 1);

if (pos >= t.size()) replace = t;

else replace = to_string(t.size() / pos) + '[' + dp[i][i + pos - 1] + ']';

if (replace.size() < dp[i][j].size()) dp[i][j] = replace;}}

return dp[0][n - 1];

}int main()

#include

using namespace std;

string encoding_string(string s)

int newlen = (len - count * len2) + 3 + len2;//壓縮後的字串長度

if (newlen < len && newlen < best_len && count > 1)//如果壓縮有效

}len2--;//重複字串長度縮短1

}if (best_count == 0)

return s;

return encoding_string(pre) + to_string(best_count) + "[" + encoding_string(cur) + "]" + encoding_string(lat);

}int main()

參考資料:

字元編碼 unicode編碼

1.ascii american standard code for information interchange 美國資訊交換標準 這是計算機上最早使用的通用的編碼方案。那個時候計算機還只是拉丁文本的專利,根本沒有想到現在計算機的發展勢頭,如果想到了,可能一開始就會使用unicode了。當時絕大...

A 字元編碼

請將一串長度為5的純字母文字譯成乙個密碼,密碼規律如下 用原來的字母後面的第4個字母代替原來的字母。如c用g代替 文字中不存在w w x x y y z z等字母 最後得到的文字即為密碼。輸入一串文字,長度固定為5。輸出對應的密碼。格式為 password is 密碼 input chinaoutp...

字元編碼 字元編碼的奧秘

字元編碼相信是每個程式設計師的噩夢,只要是有中文的地方,總是會遇到各種編碼的問題,並且這種問題還非常難纏,尤其在linux上,因為上面很多軟體都是針對 英語國家開發的,是不會考慮其他語種編碼問題。在遇到編碼的無數大坑之後,我決定仔細研究下編碼問題,因為這就像一道坎一直橫在你面前,每次到這裡你都會 跌...