简体   繁体   English

如何使用 Java 从两个字符串中打印唯一的字母?

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

Recently, I attended an interview.最近,我参加了一个采访。 They asked me to write a program to print unique alphabets and common characters from two strings.他们让我编写一个程序,从两个字符串中打印出独特的字母和常用字符。 I wrote the code below to print the common characters:我写了下面的代码来打印常用字符:

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);
}
}

but they said like they are not satisfied with my answer.但他们说他们对我的回答不满意。 I guess it's because they are not expecting retainAll .我想这是因为他们不期待retainAll So, please tell me the right way of programming to satisfy them in the future.所以,请告诉我将来满足他们的正确编程方式。

I even Googled but I didn't find any good, understandable links.我什至用谷歌搜索,但我没有找到任何好的、可理解的链接。

So, how to print unique and common characters from two strings without using retainAll ?那么,如何在不使用retainAll的情况下从两个字符串中打印唯一和常见的字符?

Any code would be appreciated.任何代码将不胜感激。

It is possible the interviewer wanted to check your understanding of the internals of how to solve this problem efficiently, and usage of retainAll() kinda misses the purpose of this task. 面试官可能希望检查您对如何有效解决此问题的内部理解,并且使用retainAll()有点错过了此任务的目的。

To implement it "from scratch" one can use several approaches: 要“从头开始”实现它,可以使用几种方法:

  1. Similar to your solution - populate two Set objects - one for each string, and then check the difference/common element between them by: 与您的解决方案类似 - 填充两个Set对象 - 每个字符串一个,然后通过以下方式检查它们之间的差异/公共元素:

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

    You can even use a bitset if the alphabet is known to be constant (and small enough), otherwise a HashSet is fine and will achieve O(n) average case performance. 如果已知字母表是常量(并且足够小),您甚至可以使用bitset,否则HashSet很好并且将实现O(n)平均大小写性能。

  2. sort and iterate: sort the two char arrays and iterate together to find common (and unique) characters. 排序和迭代:对两个char数组进行排序并一起迭代以查找常见(和唯一)字符。 While in java there is no real benefit for it (since String is immutable, so you need to create a new char[] anyway) - in other languages, it saves up space and can be done inplace with really little additional space. 虽然在java中没有真正的好处(因为String是不可变的,所以你需要创建一个新的char[] ) - 在其他语言中,它可以节省空间,并且可以在很少的额外空间内完成。

Print unique and common characters from two string without using retainAll. 不使用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(" ", ""); 

Results: 结果:

Common:danli
Unique:gvmIfebcoutsry

when you are going for an interview and if they ask for silly question like the one you said, then they are not looking for complex Collection framework. 当你去面试时,如果他们问你所说的那个愚蠢的问题,那么他们就不会寻找复杂的Collection框架。 They are looking if you can do the same at grass root level with your coding abilities keeping in mind how you write a code that will be able to handle cases even if the data provided goes into millions. 他们正在研究你是否可以在草根级别使用编码能力,同时记住如何编写能够处理案例的代码,即使提供的数据达到数百万。

This problem can be easily solved by taking an byte[]. 采用byte []可以很容易地解决这个问题。 We know that char is represented by numeric internally. 我们知道char在内部用数字表示。

so in the first iteration, just iterate over the chars of the first string(str1) and set the byte location to some constant, say 1. 所以在第一次迭代中,只迭代第一个字符串(str1)的字符并将字节位置设置为某个常量,比如1。

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

so in the second iteration, just iterate over the chars of the second string and set the byte location to some constant say 2 only if it is set to 1, and 3 to represent that it is unique to str2. 所以在第二次迭代中,只迭代第二个字符串的字符并将字节位置设置为某个常量,只有当它设置为1时才设置为2,而3表示它对于str2是唯一的。

In the third iteration, just iterate over the byte arr and print the chars(convert the index to char) where ever it is 2 for common and 1/3 for unique. 在第三次迭代中,只需迭代字节arr并打印字符(将索引转换为char),其中常见的是2,独特的是1/3。

final solution O(n) and scalable. 最终解决方案O(n)和可扩展。

s1CharSet.retainAll(s2CharSet); s1CharSet.retainAll(s2CharSet);

Seems like the above line just gave the intersection (A intersection B) . 好像上面的线只给了交点(A交点B)

To get all the Unique characcrters you need to get the UNION. 要获得所有独特的特征,您需要获得UNION。 AB + A Intersection B + BA. AB + A交点B + BA。

UPDATE: Reference : Intersect and Union 更新:参考: 相交和联盟

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;
}
   }

I would have done something like: 我会做的事情如下:

//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());

This basically just exploits the behaviour of the set add function, that it returns true if the element was not in the set, and false if it was. 这基本上只是利用了set add函数的行为,如果元素不在集合中,它返回true,如果是,则返回false。 The set avoids duplication. 该集避免了重复。

Gives the output: 给出输出:

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]

There are a couple of small points that an interviewer might pick up on: 面试官可能会提到一些小问题:

1) You used the class and not the interface in your LinkedHashSet definitions. 1)您在LinkedHashSet定义中使用了类而不是接口。 This is widely regarded as bad practice and might be taken as showing that you have limited familiarity with Java - ofc, whether that is an issue depends on what level of experience they are interested in.. 这被广泛认为是不好的做法,并且可能被视为表明您对Java-ofc的熟悉程度有限,这是否是一个问题取决于他们感兴趣的经验水平。

2) Your variable naming. 2)你的变量命名。 You are never happy as an interviewer if your candidate keeps naming objects "thingy" or functions "someFunction", a natural programmer produces helpful names for objects and functions on the fly. 如果您的候选人将对象命名为“thingy”或函数“someFunction”,那么您将永远不会成为面试官,自然程序员可以动态地为对象和函数生成有用的名称。 Again, depending on the level of experience they wanted this might or might not be an issue. 同样,根据他们想要的经验水平,这可能是也可能不是问题。

3) They might have been looking for some imagination in interpreting the question, eg to ask if whitespace was a "character" in the question, or to sort the output to make it more readable. 3)他们可能一直在寻找解释问题的想象力,例如询问空白是否是问题中的“字符”,或者对输出进行排序以使其更具可读性。 Or to ask whether to treat I and i as the same or different characters. 或者询问是否将I和i视为相同或不同的字符。

4) They might have been expecting some knowledge of the timeline of Java development, eg to say "Here I used Autoboxing, so it requires a 1.7 or later compiler." 4)他们可能一直期待Java开发时间表的一些知识,例如说“我在这里使用Autoboxing,所以它需要1.7或更高版本的编译器”。

5) You might just have taken too long, or needed too many syntax hints/corrections. 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);
    }
}

This is my solution implementing LinkedHashSet to maintain character order in the strings. 这是我实现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;
    }
}

Let say for simplicity our strings only consists of lower case characters. 简单来说,我们的字符串只包含小写字符。 Now we can construct two array of length 26 , and count the occurrence of characters . 现在我们可以构造两个长度为26的数组,并计算字符的出现次数。 Now compare both arrays , if both have count >0 ,then its common to both string . 现在比较两个数组,如果两个数组都计数> 0,那么它们对两个数组都是通用的。 If count is zero in one and non zero in other , the its unique to that particular string. 如果count在一个中为零而在另一个中为非零,则其对于该特定字符串是唯一的。 If both zero the character is not present in either string. 如果两者都为零,则字符串中不存在该字符。

The above approach could be used for many similar problems. 上述方法可用于许多类似的问题。

Print out all the Common Characters: 打印出所有常见字符:

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.

相关问题 Java-如何在不使用!@#$%^&*()的情况下从0打印到z?&gt; &lt;“:{} |字母,仅包括字母和数字 - Java - How to print from 0 to z without !@#$%^&*()?><":{}| letters, only alphabet and numbers 如何将具有唯一值的两个“字符串”合并到 java 中的新字符串? 使用转换为 arrays 或列表 - How to merge two “strings” with unique values to new String in java? Using converting to arrays or lists 比较两个json字符串并使用Java打印它们之间的差异 - Compare two json strings and print differences between them using Java 如何在Java的二维字符串数组中查找唯一元素? - How to find unique elements in a two-dimensional array of strings in java? 如何使用 Binary Search 打印两个不同 ArrayLists 中匹配索引的所有字符串? - How do I print all strings from matching indexes in two different ArrayLists using Binary Search? 如何在Java中从字母表中的“z”循环回“a”? - How to loop back from "z" to "a" in the alphabet in Java? 如何从字符串映射Java中删除/剥离唯一文本 - How to remove/stripp off unique text from a Map of Strings Java 使用两个字符串生成唯一标识符 - Generating Unique identifier using two strings 如何从ArrayList(Java)中的字符串数组中打印字符串的组合 - How to print combinations of Strings from String arrays in an ArrayList (Java) 如何将主类中的字符串存储到数组中,然后打印它-java - how to store strings from main class into an array and then print it - java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM