C++ 中的單詞縮寫


假設我們有一個包含 n 個唯一字串的陣列,我們必須根據以下規則為每個單詞生成儘可能短的縮寫。

  • 從第一個字元開始,然後是縮寫的字元數,最後是最後一個字元。

  • 如果我們發現任何衝突,即多個單詞共享相同的縮寫,則可以使用更長的字首代替僅第一個字元,直到將單詞到縮寫的對映變得唯一。

  • 當縮寫沒有使單詞變短時,則保留其原始形式。

因此,如果輸入類似於 ["like", "god", "internal", "me", "internet", "interval", "intension", "face", "intrusion"],則輸出將是

["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"]

為了解決這個問題,我們將遵循以下步驟:

  • 定義一個節點結構,它具有 cnt 和一個包含 26 個子節點的陣列,最初所有子節點都是空的。

  • 定義一個函式 freeNode(),它將接受 head 引數。

  • 如果 head 為空,則:

    • 返回

  • 對於初始化 i := 0,當 i < 26 時,更新 (i 增加 1),執行:

    • freeNode(head 的 child[i])

  • 刪除 head

  • 定義一個函式 insertNode(),它將接受 node 和 s 引數。

  • curr = node

  • 對於初始化 i := 0,當 i < s 的大小,更新 (i 增加 1),執行:

    • x := s[i]

    • 如果 node 的 child[x - 'a'] 不為空,則

      • node 的 child[x - 'a'] := 一個新節點

    • node := node 的 child[x - 'a']

    • 將 node 的 cnt 增加 1

  • 定義一個函式 abbreviate(),它將接受 node 和 s 引數。

  • ret := 空字串

  • curr = node

  • 對於初始化 i := 0,當 i < s 的大小,更新 (i 增加 1),執行:

    • x := s[i]

    • curr := curr 的 child[x - 'a']

    • 如果 curr 的 cnt 等於 1,則:

      • rem := s 的大小

      • ret := (如果 rem <= 1,則 s,否則 s 從索引 0 到 i 的子字串連線 rem 作為字串連線 s 的最後一個元素

      • 退出迴圈

  • 返回 ret

  • 定義一個函式 wordsAbbreviation(),它將接受一個數組 dict。

  • n := dict 的大小

  • 定義一個大小為 n 的陣列 ret

  • 定義一個 map m

  • 對於初始化 i := 0,當 i < n 時,更新 (i 增加 1),執行:

    • word := dict[i]

    • rem := word 的大小 - 2

    • x := (如果 rem <= 1,則 word,否則 word 的第一個元素連線 rem 連線 word 的最後一個元素)

    • 將 i 插入到 m[x] 的末尾

    • ret[i] := x

  • 對於 m 中的每個鍵值對 it,執行:

    • 如果 it 的值的長度 <= 1,則:

      • (it 增加 1)

      • 忽略以下部分,跳到下一個迭代

    • head := 一個新節點

    • 對於初始化 i := 0,當 i < it 的值的大小,更新 (i 增加 1),執行:

      • idx := it 的 value[i]

      • insertNode(head, dict[idx])

    • 對於初始化 i := 0,當 i < it 的值的大小,更新 (i 增加 1),執行:

      • idx := it 的 value[i]

      • ret[idx] := abbreviate(head, dict[idx])

    • freeNode(head)

    • (it 增加 1)

  • 返回 ret

讓我們看看下面的實現以更好地理解:

示例

 線上演示

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   }
   cout << "]"<<endl;
}
struct Node{
   int cnt;
   Node* child[26];
   Node(){
      cnt = 0;
      for(int i = 0; i < 26; i++)child[i] = NULL;
   }
};
class Solution {
   public:
   void freeNode(Node* head){
      if (!head)
      return;
      for (int i = 0; i < 26; i++) {
         freeNode(head->child[i]);
      }
      delete head;
   }
   void insertNode(Node* node, string s){
      Node* curr = node;
      for (int i = 0; i < s.size(); i++) {
         char x = s[i];
         if (!node->child[x - 'a']) {
            node->child[x - 'a'] = new Node();
         }
         node = node->child[x - 'a'];
         node->cnt++;
      }
   }
   string abbreviate(Node* node, string s){
      string ret = "";
      Node* curr = node;
      for (int i = 0; i < s.size(); i++) {
         char x = s[i];
         curr = curr->child[x - 'a'];
         if (curr->cnt == 1) {
            int rem = s.size() - (i + 2);
            ret = rem <= 1 ? s : s.substr(0, i + 1) + to_string(rem) + s.back();
            break;
         }
      }
      return ret;
   }
   vector<string> wordsAbbreviation(vector<string>& dict) {
      int n = dict.size();
      vector<string> ret(n);
      map<string, vector<int> > m;
      for (int i = 0; i < n; i++) {
         string word = dict[i];
         int rem = word.size() - 2;
         string x = rem <= 1 ? word : word.front() + to_string(rem) + word.back();
         m[x].push_back(i);
         ret[i] = x;
      }
      Node* head;
      map<string, vector<int> >::iterator it = m.begin();
      while (it != m.end()) {
         if (it->second.size() <= 1) {
            it++;
            continue;
         }
         head = new Node();
         for (int i = 0; i < it->second.size(); i++) {
            int idx = it->second[i];
            insertNode(head, dict[idx]);
         }
         for (int i = 0; i < it->second.size(); i++) {
            int idx = it->second[i];
            ret[idx] = abbreviate(head, dict[idx]);
         }
         freeNode(head);
         it++;
      }
      return ret;
   }
};
main(){
   Solution ob;
   vector<string> v =    {"like","god","internal","me","internet","interval","intension","face","intrusion"};
   print_vector(ob.wordsAbbreviation(v));
}

輸入

{"like","god","internal","me","internet","interval","intension","face","intrusion"}

輸出

[l2e, god, internal, me, i6t, interval, inte4n, f2e, intr4n, ]

更新於:2020年7月11日

831 次檢視

開啟你的職業生涯

完成課程獲得認證

開始學習
廣告
© . All rights reserved.