![](/img/trans.png)
[英]Java - How to print from 0 to z without !@#$%^&*()?><":{}| letters, only alphabet and numbers
[英]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()
有点错过了此任务的目的。
要“从头开始”实现它,可以使用几种方法:
与您的解决方案类似 - 填充两个Set
对象 - 每个字符串一个,然后通过以下方式检查它们之间的差异/公共元素:
for (Character c : set1) { if (set2.contains(c)) { System.out.println(c); } }
如果已知字母表是常量(并且足够小),您甚至可以使用bitset,否则HashSet
很好并且将实现O(n)
平均大小写性能。
排序和迭代:对两个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.