簡體   English   中英

如何使用 Java 從兩個字符串中打印唯一的字母?

[英]How to print unique alphabet from two strings using Java?

最近,我參加了一個采訪。 他們讓我編寫一個程序,從兩個字符串中打印出獨特的字母和常用字符。 我寫了下面的代碼來打印常用字符:

String s1 = "I am living in india";
String s2 = "india is a beautiful country";

char[] s1Array = s1.toCharArray();
char[] s2Array = s2.toCharArray();

LinkedHashSet<Character> s1CharSet = new LinkedHashSet<Character>();
LinkedHashSet<Character> s2CharSet = new LinkedHashSet<Character>();

for(char kc : s1Array){
    s1CharSet.add(kc);
}

for(char c: s2Array){
    s2CharSet.add(c);
}

s1CharSet.retainAll(s2CharSet);

if(s1CharSet.size()==0){
    System.out.println("There are no common characters between the two strings");
}
else{
    System.out.println(s1CharSet);
}
}

但他們說他們對我的回答不滿意。 我想這是因為他們不期待retainAll 所以,請告訴我將來滿足他們的正確編程方式。

我什至用谷歌搜索,但我沒有找到任何好的、可理解的鏈接。

那么,如何在不使用retainAll的情況下從兩個字符串中打印唯一和常見的字符?

任何代碼將不勝感激。

面試官可能希望檢查您對如何有效解決此問題的內部理解,並且使用retainAll()有點錯過了此任務的目的。

要“從頭開始”實現它,可以使用幾種方法:

  1. 與您的解決方案類似 - 填充兩個Set對象 - 每個字符串一個,然后通過以下方式檢查它們之間的差異/公共元素:

     for (Character c : set1) { if (set2.contains(c)) { System.out.println(c); } } 

    如果已知字母表是常量(並且足夠小),您甚至可以使用bitset,否則HashSet很好並且將實現O(n)平均大小寫性能。

  2. 排序和迭代:對兩個char數組進行排序並一起迭代以查找常見(和唯一)字符。 雖然在java中沒有真正的好處(因為String是不可變的,所以你需要創建一個新的char[] ) - 在其他語言中,它可以節省空間,並且可以在很少的額外空間內完成。

不使用retainAll從兩個字符串打印唯一和常用字符。

        String firstString = "I am living in india";
        String secondString = "india is a beautiful country";

        HashSet<Character> h1 = new HashSet<Character>(), h2 = new HashSet<Character>();
        for(int i = 0; i < firstString.length(); i++) {
            h1.add(firstString.charAt(i));
        }
        for(int i = 0; i < secondString.length(); i++){
            h2.add(secondString.charAt(i));
        }

        StringBuffer commonSB = new StringBuffer();
        StringBuffer uniqueSB = new StringBuffer();

        for(Character i : h1){
            if(!h2.contains(i)){
               uniqueSB.append(i);
            }else{
               commonSB.append(i);
            };
         }

         for(Character i : h2){
            if(!h1.contains(i)){
               uniqueSB.append(i);
            };
         }

         System.out.println("Common:"+commonSB.toString().replace(" ", ""); 
         System.out.println("Unique:"+uniqueSB.toString().replace(" ", ""); 

結果:

Common:danli
Unique:gvmIfebcoutsry

當你去面試時,如果他們問你所說的那個愚蠢的問題,那么他們就不會尋找復雜的Collection框架。 他們正在研究你是否可以在草根級別使用編碼能力,同時記住如何編寫能夠處理案例的代碼,即使提供的數據達到數百萬。

采用byte []可以很容易地解決這個問題。 我們知道char在內部用數字表示。

所以在第一次迭代中,只迭代第一個字符串(str1)的字符並將字節位置設置為某個常量,比如1。

for (int i=0; i<str1.length; i++) {
     byteArr[(int)str.charAt(i)] = 1; // O(1)
}

所以在第二次迭代中,只迭代第二個字符串的字符並將字節位置設置為某個常量,只有當它設置為1時才設置為2,而3表示它對於str2是唯一的。

在第三次迭代中,只需迭代字節arr並打印字符(將索引轉換為char),其中常見的是2,獨特的是1/3。

最終解決方案O(n)和可擴展。

s1CharSet.retainAll(s2CharSet);

好像上面的線只給了交點(A交點B)

要獲得所有獨特的特征,您需要獲得UNION。 AB + A交點B + BA。

更新:參考: 相交和聯盟

public class Test {

public static void main(String... args) throws Exception {

    List<String> list1 = new ArrayList<String>(Arrays.asList("A", "B", "C"));
    List<String> list2 = new ArrayList<String>(Arrays.asList("B", "C", "D", "E", "F"));

    System.out.println(new Test().intersection(list1, list2));
    System.out.println(new Test().union(list1, list2));
}

public <T> List<T> union(List<T> list1, List<T> list2) {
    Set<T> set = new HashSet<T>();

    set.addAll(list1);
    set.addAll(list2);

    return new ArrayList<T>(set);
}

public <T> List<T> intersection(List<T> list1, List<T> list2) {
    List<T> list = new ArrayList<T>();

    for (T t : list1) {
        if(list2.contains(t)) {
            list.add(t);
        }
    }

    return list;
}
   }

我會做的事情如下:

//assume questions treats I and i as the same.
    String s1 = "I am living in india".toLowerCase();
    String s2 = "india is a beautiful country".toLowerCase();

    //Since character is comparable this will maintain the set in alphabetical order when we print it. - well based on the numerical chacacter anyway.
    Set<Character> unique = new TreeSet<Character>(); 
    Set<Character> common = new TreeSet<Character>();

    unique.addAll(Arrays.<Character>asList(ArrayUtils.toObject(s1.toCharArray()))); //Oh java !?!?!
    for(Character c : s2.toCharArray()){
        if(!unique.add(c)){
            common.add(c);
        }
    }

    //Assume question didnt mean to include whitespace
    unique.remove(' ');
    common.remove(' ');

    System.out.println("Unique: " + unique.toString());
    System.out.println("Common: " + common.toString());

這基本上只是利用了set add函數的行為,如果元素不在集合中,它返回true,如果是,則返回false。 該集避免了重復。

給出輸出:

Unique: [a, b, c, d, e, f, g, i, l, m, n, o, r, s, t, u, v, y]
Common: [a, d, i, l, n, t, u]

面試官可能會提到一些小問題:

1)您在LinkedHashSet定義中使用了類而不是接口。 這被廣泛認為是不好的做法,並且可能被視為表明您對Java-ofc的熟悉程度有限,這是否是一個問題取決於他們感興趣的經驗水平。

2)你的變量命名。 如果您的候選人將對象命名為“thingy”或函數“someFunction”,那么您將永遠不會成為面試官,自然程序員可以動態地為對象和函數生成有用的名稱。 同樣,根據他們想要的經驗水平,這可能是也可能不是問題。

3)他們可能一直在尋找解釋問題的想象力,例如詢問空白是否是問題中的“字符”,或者對輸出進行排序以使其更具可讀性。 或者詢問是否將I和i視為相同或不同的字符。

4)他們可能一直期待Java開發時間表的一些知識,例如說“我在這里使用Autoboxing,所以它需要1.7或更高版本的編譯器”。

5)您可能只是花了太長時間,或者需要太多的語法提示/更正。

class uniqueCharInTwoString{
    public static void unique(String a, String b){
        HashSet<Character> unique = new HashSet<Character>();
        HashSet<Character> common = new HashSet<Character>();
        for(Character c : a.toCharArray()){
            unique.add(c);
        }
        for(Character c : b.toCharArray()){
            if(!unique.add(c)){
                common.add(c);
            }
        }
        unique.removeAll(common);
        unique.remove(' ');
        common.remove(' ');
        System.out.println(unique);
        System.out.println(common);
    }
    public static void main(String args[]){
        String a = "abdedf";
        String b = "cdfang";
        unique(a,b);
    }
}

這是我實現LinkedHashSet以維護字符串中的字符順序的解決方案。

import java.util.LinkedHashSet;
import java.util.Set;

public class CommonCharacters {
 public static void main(String[] args) {
    Pair<String, String> p = getDuplicates("abdxzewxk", "axzmnx");
    System.out.println("Unique:" + p.value1 + "  Common:" + p.value2);
}

public static Pair<String, String> getDuplicates(String s1, String s2) 
{
    Set<Character> xters1 = new LinkedHashSet<Character>();
    Set<Character> xters2 = new LinkedHashSet<Character>();

    for (char c : s1.toCharArray()) {
        xters1.add(c);
    }

    for (char c : s2.toCharArray()) {
        xters2.add(c);
    }

    Set<Character> unique = new LinkedHashSet<>();
    Set<Character> common = new LinkedHashSet<>();

    for (char c : xters1) {
        if (xters2.contains(c))
            common.add(c);
        else
            unique.add(c);
    }

    for (char c : xters2) {
        if (xters1.contains(c))
            common.add(c);
        else
            unique.add(c);
    }

    return new Pair(stringfry(common), stringfry(unique));
}

public static String stringfry(Set<Character> chrs) {
    StringBuilder sb = new StringBuilder();
    chrs.forEach(s -> {
        sb.append(s);
    });
    return sb.toString();
}


static class Pair<E, U> {
    private E value1;
    private U value2;

    public Pair(E value1, U value2) {
        this.value1 = value1;
        this.value2 = value2;
    }
}

簡單來說,我們的字符串只包含小寫字符。 現在我們可以構造兩個長度為26的數組,並計算字符的出現次數。 現在比較兩個數組,如果兩個數組都計數> 0,那么它們對兩個數組都是通用的。 如果count在一個中為零而在另一個中為非零,則其對於該特定字符串是唯一的。 如果兩者都為零,則字符串中不存在該字符。

上述方法可用於許多類似的問題。

打印出所有常見字符:

public class Test10 {
    public static void main(String[] args) {
        String a = "Gini Gina Protijayi".toLowerCase();
        String b = "Soudipta".toLowerCase();
        // print out all the common characters
        a.chars()
        .distinct()
        .mapToObj(ch -> String.valueOf((char) ch))
        .filter(b::contains)
        .forEach(System.out::println);

    }// main

}
  Try this code with your inputs, you will get the result.

  import java.util.HashSet;
    public class Practice {
        public static void main(String[] args) {
        String str1 = "Ro is Captain";
        String str2 = "Ri is keeper";

        char[] c1 = str1.toCharArray();
        char[] c2 = str2.toCharArray();`enter code here`

        HashSet hs = new HashSet();
        HashSet hf = new HashSet();
        HashSet hx = new HashSet();
        for (int i = 0; i < c1.length; i++) {
            hs.add(c1[i]);
        }
        for (int i = 0; i < c2.length; i++) {
            hs.add(c2[i]);
        }
        for (int i = 0; i < c1.length; i++) {
            hx.add(c1[i]);
        }
        for (int i = 0; i < c2.length; i++) {
            hf.add(c2[i]);
        }
        hx.retainAll(hf);
        hs.removeAll(hx);

        System.out.println("Uncommon Chars : " + hs);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM