首页 > 试题广场 >

最小唯一前缀

[编程题]最小唯一前缀
  • 热度指数:1448 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

给定一组个字符串,为每个字符串找出能够唯一识别该字符串的最小前缀。


输入描述:
第一行输入一个整数 n 表示字符串个数
后面n行,每行一个字符串,一共n串互不相同的字符串。(2 <= n <= 100,字符串长度不超过100)


输出描述:
输出n行,每行一个字符串,依次是每个字符串的最小可唯一识别前缀
示例1

输入

5
meituanapp
meituanwaimai
dianpingliren
dianpingjiehun
mt

输出

meituana
meituanw
dianpingl
dianpingj
mt

备注:
如果一个字符串S是另一个字符串T的前缀,则S的最小可识别前缀为S;
C++前缀树解法
#include<iostream>
(720)#include<vector>
#include<string>
using namespace std;
class trie_node{
public:
    int cnt;
    trie_node* next[26];
    trie_node(){
        cnt=1;
        for(int i=0;i<26;i++){
            next[i]=nullptr;
        }
    }
};
int main(){
    trie_node* root=new trie_node();
    int n=0;
    cin>>n;
    vector<string> strs(n);
    for(int i=0;i<n;i++){
        string tmp;
        cin>>tmp;
        strs[i]=tmp;
        trie_node* p=root;
        for(int j=0;j<tmp.length();j++){
            if(p->next[tmp[j]-'a']!=nullptr){
                p->next[tmp[j]-'a']->cnt++;
            }
            else{
                p->next[tmp[j]-'a']=new trie_node();
            }
            p=p->next[tmp[j]-'a'];
        }
    }
    for(int i=0;i<n;i++){
        trie_node* p=root;
        int j=0;
        for(;j<strs[i].length();j++){
            if(p->next[strs[i][j]-'a']->cnt == 1){
                cout<<strs[i].substr(0,j+1)<<endl;
                break;
            }
            p=p->next[strs[i][j]-'a'];
        }
        if(j==strs[i].length()){
            cout<<strs[i]<<endl;
        }
    }
    return 0;
}

发表于 2020-03-10 22:34:41 回复(3)
cdf头像 cdf
暴力比较字符串hash值
#include<bits/stdc++.h>
using namespace std;
int n;
int mod=1e9+7;
vector<string> v,v2;
bool vis[200];
int h[200];
int main(){
    ios::sync_with_stdio(0);
    cin>>n;
    v=vector<string>(n);
    v2=vector<string>(n);
    for (int i=0;i<n;i++){
        cin>>v[i];
    }
    memset(vis,0,sizeof(vis));
    memset(h,0,sizeof(h));
    int w=1;
    for (int i=0;i<100;i++){
        for (int j=0;j<n;j++){
            if(vis[j] || i>=v[j].size()){
                continue;
            }
            h[j]=(h[j]+w*(v[j][i]))%mod;
        }
        for (int j=0;j<n;j++){
            if(vis[j]) continue;
            bool f=true;
            for (int k=0;k<n;k++){
                if(j==k || vis[k] ){
                    continue;
                }
                if(h[j]==h[k]){
                    f=false;
                    break;
                }
            }
            if(f){
                vis[j]=true;
                v2[j]=v[j].substr(0,i+1);
            }
        }
        w=(w*137)%mod;
    }
    for (auto s:v2){
        cout<<s<<endl;
    }
}


发表于 2020-03-10 23:37:53 回复(0)

trie树

#include <bits/stdc++.h>
using namespace std;

const int N = 10010;
int son[N][26], cnt[N], idx;
int n;

void insert(string &str){
    int p = 0;
    for (int i = 0; str[i]; i++){
        int u = str[i] - 'a';
        if (!son[p][u]) son[p][u] = ++idx;
        // 计算每个字符出现的次数
        cnt[son[p][u]]++;
        p = son[p][u];
    }

}

string query(string &str){
    int p = 0;
    for (int i = 0; str[i]; i++){
        int u = str[i] - 'a';
        // 出现次数为1的字符为终点的字符串为最小前缀
        if (cnt[son[p][u]] == 1) return str.substr(0, i + 1);
        p = son[p][u];
    }
    return str;
}

int main(){

    cin >> n;
    vector strs;
    while (n--) {
        string str;
        cin >> str;
        insert(str);
        strs.push_back(str);
    }

    for (auto && x : strs){
        cout << query(x) << endl;
    }

    return 0;
}
编辑于 2022-05-16 16:53:28 回复(0)
python字典树版本,创建一个字典树,之后进行如下操作:
1.对于每一个单词,将其他单词插入字典树,然后再寻找本单词每一个字母是否在字典树中,在的话就证明不能唯一表示单词,就添加本单词。
2.如果不在的话,就返回结果。
class solution:
    def __init__(self):
        self.pretree={}
    def inset(self,a):
        temp=self.pretree
        for x in a:
            if x not in temp:
                temp[x]={}
            temp=temp[x]
    def core(self,a):
        temp=self.pretree
        res=''
        for x in a:
            if x in temp:
                res+=x
                temp=temp[x]
            else:
                res+=x
                return res
        return res
n=int(input())
strings=[]
res=[]
for i in range(n):
    strings.append(input())
for string in strings:
    a=solution()
    for string_else in strings:
        if string==string_else:
            continue
        a.inset(string_else)
    res.append(a.core(string))
for x in res:
    print(x)


发表于 2020-07-11 22:01:05 回复(0)
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <string.h>
#include <memory>

using namespace std;

class Trie
{

public:
    struct Node
    {
        map<char, shared_ptr<Node>> subs;
        int cnt;

        Node()
        {
            cnt = 1;
        }
    };

    typedef map<char, shared_ptr<Node>>::iterator SubsIter;

    Trie()
    {
        root = make_shared<Node>();
    }
    void build(const string &str)
    {
        shared_ptr<Node> tmp = root;
        int len = str.length();
        SubsIter iter;
        for (int idx = 0; idx < len; ++idx)
        {
            iter = tmp->subs.find(str[idx]);
            if (iter == tmp->subs.end())
            {
                shared_ptr<Node> new_node = make_shared<Node>();
                tmp->subs.insert(make_pair(str[idx], new_node));
            }else{
                ++iter->second->cnt;
            }
            tmp = tmp->subs[str[idx]];
        }
    }
    string min_pre(const string &str)
    {
        shared_ptr<Node> tmp = root;
        int len = str.length();
        SubsIter iter;
        for (int idx = 0; idx < len; ++idx)
        {
            iter = tmp->subs.find(str[idx]);
            if (iter == tmp->subs.end())
            {
                return "";
            }
            if (iter->second->cnt == 1)
            {
                return str.substr(0, idx + 1);
            }
            tmp = iter->second;
        }
        return str;
    }

private:
    shared_ptr<Node> root;
};

int main()
{
    int n;
    cin >> n;
    vector<string> cell(n);
    Trie tree;
    for (int idx = 0; idx < n; ++idx)
    {
        cin >> cell[idx];
        tree.build(cell[idx]);
    }

    for(int idx = 0; idx < n; ++ idx)
    {
        cout<<tree.min_pre(cell[idx])<<endl;
    }

    return 0;
}

发表于 2022-05-11 17:22:31 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String[] ss = new String[n];
        String[] res = new String[n];
        for (int i = 0; i < n; i++) {
            ss[i] = sc.next();
            res[i] = ss[i];
        }
        //从第一个字符串开始寻找
        for (int j = 0; j < n; j++) {
            //从第一个字符开始寻找最短前缀
            for (int i = 0; i <= ss[j].length(); i++) {
                boolean *** = true;
                //每个字符串寻找一次
                for (String cur : ss) {
                    //TODO 排除当前
                    if (!ss[j].equals(cur) && cur.length() >= i && ss[j].substring(0, i).equals(cur.substring(0, i))) {
                        //匹配上了说明当前长度不够
                        *** = false;
                        break;
                    }
                }
                if (***) {
                    res[j] = ss[j].substring(0, i);
                    break;
                }
            }
        }
        for (int i = 0; i < n; i++) {
            System.out.println(res[i]);
        }
    }
}


发表于 2021-02-20 19:23:27 回复(0)
暴力:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
 
 
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        List<String> list = new ArrayList<>();
        for (int i = 0; i < n ; i++) {
            list.add(scanner.nextLine());
        }
        List<String> match = match(list);
        for (String element : match){
            System.out.println(element);
        }
    }
 
    /**
     * 思路: 使用暴力破解法
     * (1)、 匹配第一个字符观察其他字符是否也出现此字符,出现则继续匹配往下匹配,直至其他字符串在此索引下无相同的字符,或者该字符串匹配到最后一个
     * (2)、该字符穿即时最小可识别前缀
     */
 
    private static List<String> match(List<String> list) {
        List<String> returnList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            String matchString = list.get(i);
            int beMaxLength = Integer.MIN_VALUE;
            for (int j = 0; j < list.size(); j++) {
                int index = 0;
                if(j == i){
                    continue;
                }
                String beMatchString = list.get(j);
                while (index < matchString.length() && index < beMatchString.length()
                        && matchString.charAt(index) == beMatchString.charAt(index)) {
                    index++;
                }
                beMaxLength = Math.max(index, beMaxLength);
            }
            if(beMaxLength == matchString.length()){
                   returnList.add(matchString.substring(0,beMaxLength));
            }else{
                  returnList.add(matchString.substring(0,beMaxLength + 1));
            }
        }
        return returnList;
    }
}


发表于 2020-10-25 14:16:20 回复(0)
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
class Node {
public:
    int count = 1;
    unordered_map<char, Node*> child;
};
int main()
{
    int n;
    cin >> n;
    vector<string> strs(n);
    auto root = new Node();
    for (int i = 0; i < n; i++)
    {
        string input;
        cin >> input;
        strs[i] = input;
        auto ptr = root;
        for (int j = 0; j < input.size(); j++) {
            if (ptr->child.find(input[j]) == ptr->child.end()) {
                ptr->child.insert({ input[j],new Node() });
            }
            else
                ptr->child[input[j]]->count++;
            ptr = ptr->child[input[j]];
        }
    }
    for (int i = 0; i < n; i++) {
        auto ptr = root;
        int j = 0;
        while (j < strs[i].size() && ptr->child[strs[i][j]]->count != 1)
        {
            ptr = ptr->child[strs[i][j++]];
        }
        cout << strs[i].substr(0, j + 1) << endl;
    }
}

编辑于 2020-10-10 19:37:29 回复(0)
def commonSubingString(s, t):
    if s == t:
        return 0
    n = 0
    for ss, tt in zip(s, t):
        if ss == tt:
            n += 1
        else:
            break
    return n
 
 
if __name__ == '__main__':
    n = int(input())
    data = []
    for i in range(n):
        data.append(input())
    for d in data:
        r = max([commonSubingString(d, t) for t in data])
        print(d[:min(r + 1, len(d))])
python 暴力解法,直接搜索目标字符串和其他字符串最长前缀,然后在此基础上+1。
发表于 2020-08-03 17:36:11 回复(0)
import java.util.*;

public class Main {
        public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.valueOf(sc.nextLine());

        List<MyC> strs = new ArrayList<>();
        String[] ans = new String[n];
        
        for (int i = 0; i < n; i++) {
            strs.add(new MyC(sc.nextLine(), i));
            if(strs.get(i).s.length() == 0) {
                ans[i] = "";
            }
        }
        if (n == 1) {
            System.out.println(strs.get(0).s.substring(0, 1));
        } else {
            dfs(strs, 0, ans);
            for (String w : ans) {
                System.out.println(w);
            }
        }
        
    }


    private static void dfs(List<MyC> list, int cur_idx, String[] ans) {
        if (list == null || list.size() == 0) {
            return ;
        }
        if (list.size() == 1) {
            MyC w = list.get(0);
            ans[w.idx] = w.s.substring(0, cur_idx);
            return;
        }
        List<MyC>[] rec = new ArrayList[128];
        for (int i = 0; i < 128; i++) {
            rec[i] = new ArrayList<>();
        }
        for (MyC myC : list) {
            if (myC.s.length() == cur_idx) {
                ans[myC.idx] = myC.s;
            } else {
                rec[myC.s.charAt(cur_idx)].add(myC);
            }
        }
        for (List<MyC> myCS : rec) {
            dfs(myCS, cur_idx + 1, ans);
        }
    }
}


class MyC {
    String s;
    int idx;
    MyC (String s, int idx) {
        this.s = s;
        this.idx = idx;
    }
}

发表于 2020-07-22 15:22:56 回复(0)
//不需要创建树,通过递归解决,隐式的字典树
import java.util.*;

public class Main{
   
    static Map<String, String> map = new HashMap<>();
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        scan.nextLine();
        String[] s = new String[n];
        List<String> list = new ArrayList<>();
        for(int i= 0; i<n; i++){
            s[i] = scan.nextLine();
            list.add(s[i]);
        }
        helper(list, 0);
        for(int i= 0; i<n; i++){
            System.out.println(map.get(s[i]));
        }
    }
    public static void helper(List<String> list, int level){
        if(list.size()==1){
            map.put(list.get(0), list.get(0).substring(0, level));
            return;
        }
        for(int i = 0; i<list.size(); i++){
            if(level == list.get(i).length()){
                  map.put(list.get(i), list.get(i));
                  list.remove(i);
                  i--;
            }
        }
        int[] visited = new int[list.size()];
        for(int i = 0; i<list.size(); i++){
            if(visited[i] == 0){
                List<String> temp = new ArrayList<>();
                int t = list.get(i).charAt(level);
                for(int j = i; j<list.size(); j++){
                    if(list.get(j).charAt(level)==t){
                        temp.add(list.get(j));
                        visited[j]=1;
                    }
                }
                if(list.size()>0)
                    helper(temp, level+1);
            }
        }
    }
    
}



发表于 2020-06-21 00:20:08 回复(0)
根据一楼大佬的思路,做了内存释放。
//  题目:https://www.nowcoder.com/test/question/done?tid=33823885&qid=894534#summary

#include <iostream>
#include <string>
#include <vector>
#include <array>

class Trie {
public:
  Trie()  { root_ = new TreeNode; }
  ~Trie() {__destroy(root_);      }

  void insert(std::vector<std::string>&& words) { 

    for(const auto& word : words) { 
      TreeNode* curr = root_;
      for(const auto& ch : word) { 
        int idx = ch-'a';

        if(curr->nexts[idx] ==nullptr) 
        { 
          curr->nexts[idx] = new TreeNode;
        }
        else 
        {
          ++curr->nexts[idx]->path;
        }

        curr = curr->nexts[idx];
      }
    }

    words_.swap(words);
  }

  // 那些公共前缀的 path 值肯定大于1
  // 主要找到大于1的path,就是该分支单词最短可识别前缀
  void solve() { 
    for(const auto& word : words_) { 
      TreeNode* curr = root_;
      int idx=0;

      for(; idx < word.size(); ++idx) {
        int index = word[idx]-'a';
        if(curr->nexts[index]->path ==1) 
        { 
          std::cout<<word.substr(0, idx+1)<<std::endl; 
          break;
        }

        curr = curr->nexts[index];
      }

      if(idx == word.size()) {
        std::cout<<word<<std::endl;
      }
    }
  }

private:
  struct TreeNode { 
    uint64_t path; // 经过某个单词的次数
    std::array<TreeNode*, 26> nexts;

    TreeNode() : path(1)
    {
      nexts.fill(nullptr);
    }
  };

  // 析构创建的节点
  void __destroy(TreeNode* root) { 
    if(root ==nullptr) 
      return;

    for(const auto& node : root->nexts) { 
      __destroy(node);
    }

    delete root;
    root =nullptr;
  }

  TreeNode* root_;
  std::vector<std::string> words_;
};


int main(int argc, char const *argv[]) {

  int N=0;
  std::cin>>N;
  std::vector<std::string> words;
  words.reserve(N);

  std::string word;
  while(N--) { 
    std::cin>>word;
    words.emplace_back(std::move(word));
  }

  Trie* trie = new Trie;
  trie->insert(std::move(words));
  trie->solve();

  delete trie;
  trie =nullptr;

  return 0;
}



发表于 2020-06-04 14:53:57 回复(0)
前缀树
#include<iostream>
(720)#include<vector>
#include<unordered_map>
using namespace std;

struct Node {
	string data = "";
	int cnt = 0;
	unordered_map<char, Node*> nexts;
};

void getRes(Node* node, unordered_map<string, string>&res,string& tmp) {
	if (node == NULL) return;
	if (node->data != "")
		res[node->data] = tmp;
	if (node->cnt == 1) {
		string str(tmp);
		while (node->nexts.size() > 0) {
			str += node->nexts.begin()->first;
			node = node->nexts.begin()->second;
		}
		res[node->data] = tmp;
	}
	else {
		for (auto it = node->nexts.begin(); it != node->nexts.end(); ++it) {
			tmp += it->first;
			getRes(it->second, res, tmp);
			tmp.pop_back();
		}
	}
}

void minPrefix(vector<string>& strs) {
	Node* head = new Node();
	for (auto& str : strs) {
		Node* node = head;
		for (int i = 0; i < str.size(); ++i) {
			if (node->nexts.find(str[i]) == node->nexts.end())
				node->nexts[str[i]] = new Node();
			node = node->nexts[str[i]];
			node->cnt++;
		}
		node->data = str;
	}
	unordered_map<string, string>res;
	string tmp = "";
	getRes(head, res, tmp);
	for (int i = 0; i < strs.size(); ++i) {
		strs[i] = res[strs[i]];
	}
}

int main() {
	int n;
	cin >> n;
	vector<string>strs(n);
	for (int i = 0; i < n; ++i)
		cin >> strs[i];
	minPrefix(strs);
	for (int i = 0; i < n; ++i)
		cout << strs[i] << endl;
}


编辑于 2020-05-12 22:54:59 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=Integer.valueOf(scan.nextLine());
        String ss[]=new String[n];
        for(int i=0;i<n;i++){
            ss[i]=scan.nextLine();
        }
        String s1[]=new String[n];
        for(int i=0;i<n;i++){
            int t=0;
            boolean flage=true;
            while(flage==true){
                flage=false;
                for(int j=0;j<i;j++){
                    if(ss[j].length()>t)
                        if(ss[j].charAt(t)==ss[i].charAt(t))
                            flage=true;
                }
                for(int j=i+1;j<n;j++){
                    if(ss[j].length()>t)
                        if(ss[j].charAt(t)==ss[i].charAt(t))
                            flage=true;
                }
                t++;
                if(t>=ss[i].length())
                    flage=false;
            }
            s1[i]=ss[i].substring(0,t);

        }
        for(int i=0;i<n;i++){
            System.out.println(s1[i]);
        }

    }
}

发表于 2020-05-11 22:54:33 回复(0)
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        minPrefix();
    }
 
    private static void minPrefix() {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        String[] strs = new String[n];
        int maxLen = 0;
        for (int i = 0; i < n; i++) {
            strs[i] = scanner.next();
            maxLen = Math.max(maxLen, strs[i].length());
        }
 
        int[] minLen = new int[n]; // minLen[i]: strs[i]的最小前缀长度
 
        for (int i = 1; i <= maxLen; i++) {
            Map<String, Integer> map = new HashMap<>();
            for (int j = 0; j < n; j++) {
                if(minLen[j] != 0)
                    continue;
                if(i == strs[j].length()) {
                    minLen[j] = i;
                }
                String str = strs[j].substring(0, i);
                map.put(str, map.getOrDefault(str, 0) + 1);
            }
 
            for(int j = 0; j < n; j++){
                if(minLen[j] != 0)
                    continue;
 
                String str = strs[j].substring(0, i);
                if(map.get(str) == 1)
                    minLen[j] = i;
            }
        }
        for(int i = 0; i < n; i++){
            System.out.println(strs[i].substring(0, minLen[i]));
        }
    }
}

发表于 2020-03-24 20:16:11 回复(0)
#include<iostream>
(720)#include<string>
#include<vector>
(721)#include<algorithm>
#include<unordered_map>
 
using namespace std;
 
int main(){
    int N;
    cin>>N;
    vector<string> vec;
    string temp;
    size_t max_len=0; // 所有字符串最大长度
    for(int i=0;i<N;i++){
        cin>>temp;
        max_len=max(max_len, temp.size());
        vec.push_back(temp);
    }
    vector<int> pre_len(vec.size(),0); // 所有字符串前缀长度,初始为0
    // 遍历前缀长度
    for(int i=1;i<=max_len;i++){
        // 若前缀长度为i,将所有字符串的前缀统计个数
        unordered_map<string, int> map;
        for(int j=0;j<vec.size();j++){
            if(pre_len[j]>0) continue;
            string pre=vec[j].substr(0,i);
            if(map.find(pre)==map.end()){
                map[pre]=1;
            }else{
                map[pre]++;
            }
        }
        
        // 前缀个数为1的,可以作为其最终的前缀结果
        for(int j=0;j<vec.size();j++){
            if(pre_len[j]>0) continue;
            string pre=vec[j].substr(0,i);
            if(map[pre]==1) pre_len[j]=i;
        }
    }
     
    for(int i=0;i<pre_len.size();i++){
        cout<<vec[i].substr(0,pre_len[i])<<endl;
    }
    return 0;
}

发表于 2020-03-22 21:37:02 回复(0)
//前缀树
import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        sc.nextLine();
        String[] strArr=new String[n];
        PrefixTree tree=new PrefixTree();
        for(int i=0;i<n;i++){
            strArr[i]=sc.nextLine();
            tree.insert(strArr[i]);
        }
        for(String s:strArr)
            System.out.println(tree.findMaxPrefix(s));
    }
    public static class TreeNode{
        public int path;
        public int end;
        public HashMap<Character,TreeNode> map;
        public TreeNode(){
            path=0;
            end=0;
            map=new HashMap<Character,TreeNode>();
        }
    }
    public static class PrefixTree{
        private TreeNode root;
        public PrefixTree(){
            root=new TreeNode();
        }
        public void insert(String word){
            if(word==null)
                return;
            char[]chs=word.toCharArray();
            TreeNode node=root;
            for(int i=0;i<chs.length;i++){
                if(!node.map.containsKey(chs[i]))
                    node.map.put(chs[i],new TreeNode());
                node=node.map.get(chs[i]);
                node.path++;
            }
            node.end++;
        }
        public String findMaxPrefix(String word){
            if(word.isEmpty())
                return "";
            TreeNode node=root;
            String res="";
            char[]chs=word.toCharArray();
            for(int i=0;i<chs.length;i++){
              if(node.map.containsKey(chs[i])){
                  node=node.map.get(chs[i]);
                  res+=chs[i];
                  if(node.path==1)
                      return res;
              }else
                  return "";
            }
            return res;
        }
    }
}

发表于 2020-03-22 17:02:34 回复(0)
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


public class Main {


    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        scanner.nextLine();
        String[] strings = new String[num];
        for(int i=0; i<num; ++i){
            strings[i] = scanner.nextLine();
        }
        scanner.close();
        TreeNode treeNode = new TreeNode();
        for(int i=0; i<num; ++i){
            treeNode.insert(strings[i]);
        }
        for(int i=0; i<num; ++i){
            treeNode.prefix(strings[i]);
        }
    }

    static class TreeNode{

        private int path;
        private boolean isWord;
        private Map<Character, TreeNode> next;

        public TreeNode(){
            path = 0;
            next = new HashMap<Character, TreeNode>();
            isWord = false;
        }

        public void insert(String s){
            TreeNode curr = this;
            for(int i=0; i<s.length(); ++i){
                char c = s.charAt(i);
                ++curr.path;
                if(curr.next.containsKey(c)){
                    curr = curr.next.get(c);
                }else {
                    curr.next.put(c, new TreeNode());
                    curr = curr.next.get(c);
                }
            }
            curr.isWord = true;
        }

        public void prefix(String s){
            TreeNode curr = this;
            for(int i=0; i<s.length(); ++i){
                if(curr.next.get(s.charAt(i)).isWord){
                    if(i==(s.length()-1)){
                        System.out.println(s.substring(0,i+1));
                        break;
                    }else {
                        curr = curr.next.get(s.charAt(i));
                    }
                }else{
                    if(curr.next.get(s.charAt(i)).path==1){
                        System.out.println(s.substring(0,i+1));
                        break;
                    }
                    curr = curr.next.get(s.charAt(i));
                }
            }
        }
    }
}



发表于 2020-03-19 15:24:58 回复(0)
// 不会高大上的前缀树,只能用hash表暴力解了😢
#include <vector>
#include <unordered_map>

using namespace std;

int main()
{
    string in;
    int n;
    cin >> in;
    n = atoi(in.c_str());
    vector<string> strContainer(n);
    vector<string> resContainer(n);
    vector<bool> flagContainer(n);
    unordered_map<char, int> hashMap; // alphabet: number
    int len = 0;

    for (int i = 0; i < n; i++) {
        cin >> in;
        len = in.length() > len ? in.length() : len;
        strContainer[i] = in;
        resContainer[i] = string();
        flagContainer[i] = false;
    }
    for (int i = 0; i< len; i++) {
        // hash first
        for (int j = 0; j < n; j++) {
            if (hashMap.find(strContainer[j][i]) == hashMap.end())
                hashMap[strContainer[j][i]] = 1;
            else
                hashMap[strContainer[j][i]] += 1;
        }
        // find duplicates
        for (int j = 0; j < n; j++) {
            if (strContainer[j][i] == '\0')
                flagContainer[j] = true;
            if (flagContainer[j] == true) 
                continue;
            if (hashMap[strContainer[j][i]] == 1)
                flagContainer[j] = true;
            resContainer[j] += strContainer[j][i];
        }
        // clear hash map
        hashMap.erase(hashMap.begin(), hashMap.end());
    }
    for (string s: resContainer) {
        cout << s << endl;
    }

    return 0;
}
发表于 2020-03-12 22:49:46 回复(0)
import java.util.*;
public class Main{
    public static String iskmp(String a,String b){
       int n = (a.length()>=b.length())? b.length() : a.length();
    for(int i=0;i<n;i++){
      if(a.charAt(i)!=b.charAt(i)){
        return a.substring(0,i);
      }
    }
    return (a.length()>=b.length())? b : a;
    }
    public static void main(String[] args){
       Scanner in = new Scanner(System.in);
    int n = in.nextInt();
    List<String> strs = new ArrayList<>();
    for(int i=0;i<n;i++){
      String ne = in.next();
      strs.add(ne);
    }
    String[] result = new String[n];
    for(int i=0;i<strs.size();i++){
      int max=0;
          for(int j=0;j<strs.size();j++){
            if(i==j){
              continue;
            }
            int now = iskmp(strs.get(i),strs.get(j)).length();
            if(now>max){
              max = now;
            }
          }
          if(strs.get(i).length()==max){
            result[i]=strs.get(i);
          }
          else {
            result[i] = strs.get(i).substring(0, max + 1);
          }
    }
    for(int i=0;i<n;i++){
      System.out.println(result[i]);
    }
    }
}

发表于 2020-03-12 17:33:36 回复(0)