来自 2 个(或更多)字符串的压缩字符串 - "AB" + "YZ" = "AYBZ"
Zipped String from 2 (or more) Strings - "AB" + "YZ" = "AYBZ"
所以我正在尝试 return 从压缩在一起的 2 个输入句子中提取另一个字符串。如果 2 个句子的长度相同,它将产生实际输出。如果两个输入句子的长度不相同,那么它将只是 return 一个空字符串。到目前为止,这是我的代码,但我无法弄清楚如何正确压缩单词,有人可以帮助我吗?顺便说一句,如果你能以递归方式帮助我,那就太好了,因为我正在努力练习。
例如:
Zippppp("ABC", "123") will return "A1B2C3"
Zippppp("AD", "CCC") will return “”
public class Zippppp
{
public Zippppp(String a, String s)
{
int l1 = a.length();
int l2 = s.length();
if(l1 == l2)
for(int i = 0; i > l1; i++)
System.out.print( a.substring(0, 1) + s.substring(0, 1));
}
public static void main(String args[ ])
{
Zippppp sv = new Zippppp("ABC", "123");
System.out.print(sv);
}
}
您当前正在实例化 Zippppp
个实例并作为实例化的副作用进行打印。这不是构造函数的目的,创建一个 static
方法和 return 一个 String
。并使用StringBuilder
。像,
public static String Zippppp(String a, String s) {
StringBuilder sb = new StringBuilder();
if (a != null && s != null && a.length() == s.length()) {
for (int i = 0; i < a.length(); i++) {
sb.append(a.charAt(i)).append(s.charAt(i));
}
}
return sb.toString();
}
然后调用它
System.out.println(Zippppp("ABC", "123"));
我喜欢你的 class 名字。此致
为了真正“return”,你可以实现类似于下面的例子。
Update/Edit:原始答案在下面,因为三种新方法(不关心要压缩的字符串数量)在最上面。
[MultiThreaded
]
要压缩的每个单词都由一个线程处理。为什么?问问自己:为什么不呢???
无聊使事情发生。
每个词都将由自己的线程可爱地处理。由于 AtomicInteger
.
,线程会自行组织以便不处理相同的单词并设置相同的位置
String[] mix =new String[]{"AAAZZZ","100001","BBBWWW","200002","CCCYYY","300003",
"DDDXXX", "400004","EEEWWW","5000005","FFFVVV","600006"};
int strl = mix[0].length(); //entry's length
int nwords = mix.length; //number of strings
char[] zip=new char[strl*nwords]; //the result
AtomicInteger myWord = new AtomicInteger(0);
//returning boolean if want to check some future failed(not here lol)
List<Callable<Boolean>> callables = new ArrayList<>(nwords);
Callable<Boolean> zipYours =
new Callable<Boolean>()
{
public Boolean call()
{
try
{
int mine = myWord.getAndIncrement();
for (int x=0; x < strl; x++)
zip[mine+(nwords*x)]=mix[mine].charAt(x);
}catch(Exception e) {
return false;
}
return true;
}
};
for (int i=0;i<nwords;i++)
callables.add(zipYours);
//one thread - one word - true loef
ExecutorService executor = Executors.newFixedThreadPool(nwords);
executor.invokeAll(callables);
executor.shutdown();
System.out.println(new String(zip));
/*A1B2C3D4E5F6A0B0C0D0E0F0A0B0C0D0E0F0Z0W0Y0X0W0V0Z0W0Y0X0W0V0Z1W2Y3X4W0V6*/
这是必须的吗?当然不是。不过挺好玩的,女朋友叫我做的。
骗人,我没有女朋友。你真的认为如果我有一个我会这样做吗??
[Zip'em all
]
两种不同的方法:
1.直接移动
无论要压缩的字符串数量如何,从 2 到 n 都有效。*这意味着这些方法也是旧方法的替代品,因为您可以调用 getStringsZippedDirectMove("ABC,"123")
或 getStringsZippedDirectMove(yourArray)
.
在这种方法中,每个字符串一次都被完全分配,因此列表中的每个元素只有 accessed/processed 一次。主循环根据数组中元素的数量进行迭代:
public static String getStringsZippedDirectMove(String... mix)
{
if (!goodMix(mix))
return "woloolooO"; //you are a blue monk now
int cn = mix[0].length(), n = mix.length; //cn = 3 | n = 6
char[] zip=new char[cn*n];
for (int i=0; i<n; i++)
for (int x=0; x<cn; x++)
zip[i+(n*x)] = mix[i].charAt(x);
return new String(zip);
}
boolean goodMix(String ... mix)
{
if (mix.length<2)
return false;
for (int i=1; i<mix.length; i++)
if (mix[i].length()!=mix[0].length())
return false;
return true;
}
例如,对于第一个字符串:"AAA
":
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*0)]=mix[0].charAt(0);
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*1)]=mix[0].charAt(1);
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*2)]=mix[0].charAt(2);
zip[0]=A zip[6]=A zip[12]=A
对于最后一个字符串:“789
”:
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*0)]=mix[5].charAt(0);
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*1)]=mix[5].charAt(1);
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*2)]=mix[5].charAt(2);
zip[5]=7 zip[11]=8 zip[17]=9
相同的输出:
String[] mix =new String[] { "AAA","123","BBB","456","CCC","789"};
System.out.println(getStringsZippedDirectMove(mix)); //"A1B4C7A2B5C8A3B6C9"
每次迭代都会导致 String 元素的字符完全重定位。
2。从索引开始多次移动 - Holger 风格
受到 Holger 评论的启发
无论要压缩的字符串数量如何,从 2 到 n。*
public String getStringsZippedHolger(String ... mix)
{
if (!goodMix(mix))
return "woloolooO"; //you are a red monk now
char[] zip = new char[mix[0].length()*mix.length];
for (int i=0, j=0; i<mix[0].length(); i++)
for (String s : mix)
zip[j++] = s.charAt(i);
return new String(zip);
}
主循环迭代三次,因为它基于每个文本的长度 (3)。在每次迭代中,它将在 j
标记的索引中的数组中的每个字符串中附加位置 i
处的字符。最后一个计数器在每次分配时递增。
String[] mix =new String[] { "AAA","123","BBB","456","CCC","789"};
System.out.println(getStringsZippedHolger(mix)); // "A1B4C7A2B5C8A3B6C9"
System.out.println(getStringsZippedHolger("HLE","OGR"));
System.out.println(getStringsZippedHolger("IT S","SHBS"," EO "));
原答案块(2串)
Arrays
每次迭代双重赋值
public String getZippppppppppppppppppppppppp(String a, String s) //a -"ABC" s -"123"
{
if (s.length()!=a.length())
return "";
char[] zip=new char[s.length()*2];
for (int i=0; i<s.length(); i++)
{
zip[i*2] = a.charAt(i);
zip[(i*2)+1] = s.charAt(i);
}
return new String(zip); /* "A1B2C3" */
}
遍历任何字符串的长度并按顺序插入每个元素。在迭代期间,这是分配的值:
i = 0 i = 1 i = 2
--------------------------------------------------------
zip[0] = A zip[2] = B zip[4] = C
zip[1] = 1 zip[3] = 2 zip[5] = 3
可怕的油漆:
结果,我们得到:
zip = ['A','1','B','2','C','3']
|||
new String(zip) = "A1B2C3"
注:不爱数组就没有炉石
每次迭代单次赋值
这对迭代逻辑使用了另一种方法,当您可以执行上一个示例所做的操作时,这似乎完全没用。但只是为了好玩。
static String getZipppppppppppppppppppppUsingCharAtThanksElliot(String a, String s)
{ //a -"ABC" s -"123"
if (a.length()!=s.length())
return "";
char[] zip = new char[s.length()*2];
int c=0;
boolean even = false;
for(int i =0; i < (s.length()*2); i++)
{
even =!even;
if (even)
zip[i] = a.charAt(c);
else
{
zip[i] = s.charAt(c);
c++;
}
}
return new String(zip); //--> "A1B2C3"
}
String#subString
:
public String getZippppppppppppppppppppppppp(String a, String s) //a -"ABC" s -"123"
{
if (a.length()!=s.length())
return "";
String line="";
for(int i = 0; i < s.length(); i++)
line += ( a.substring(i*1, (i*1)+1) + s.substring(i*1, (i*1)+1) );
return line; //--> "A1B2C3"
}
可能是性能最差的方法。
String#charAt
请注意 charAt()
,在 Elliot 的回答中正确指出,不适用于此逻辑;它会给你一个数字文本,作为添加它们各自的 unicode 值的结果。它不会附加字符。
使用 charAt()
的替代方法是使用 空字符串解决方法 ,或者像第二个无聊的示例那样创建 char[]
。
public String getZipppppppppppppppppppppUsingCharAtThanksElliot(String a, String s)
{ //a -"ABC" s -"123"
if (a.length()!=s.length())
return "";
String line="";
for(int i = 0; i < s.length(); i++)
line += a.charAt(i) + "" + s.charAt(i) ; //note the empty string
return line; //--> "A1B2C3"
}
不要在字符串上使用 charAt
、substring
- 使用
charAt
和 substring
假设 String
中的字符位于基本多语言平面 (BMP)
- 对于补充平面 (SP) 中的任何字符,这些假设将给出无效字符
使用代码点
- 代码点应成为默认值,任何使用
char
的处理都应弃用
- 使用番石榴
Streams.zip
(这是很长一段时间的测试版,我们可以依赖)
import com.google.common.collect.Streams;
import java.util.stream.Collectors;
class Zippppp {
private final String zipped;
public Zippppp(String a, String b) {
zipped = Streams.zip(a.codePoints().boxed(), b.codePoints()
.boxed(), (x, y) -> new String(Character.toChars(x)) + new String(Character.toChars(y)))
.collect(Collectors.joining());
}
public static void main(String[] args){
System.out.println(new Zippppp("\uD83D\uDE00\uD83D\uDE00\uD83D\uDE00", "123").zipped); // 123
System.out.println(new Zippppp("ABC", "12").zipped); // A1B2
}
}
所以我正在尝试 return 从压缩在一起的 2 个输入句子中提取另一个字符串。如果 2 个句子的长度相同,它将产生实际输出。如果两个输入句子的长度不相同,那么它将只是 return 一个空字符串。到目前为止,这是我的代码,但我无法弄清楚如何正确压缩单词,有人可以帮助我吗?顺便说一句,如果你能以递归方式帮助我,那就太好了,因为我正在努力练习。
例如:
Zippppp("ABC", "123") will return "A1B2C3"
Zippppp("AD", "CCC") will return “”
public class Zippppp
{
public Zippppp(String a, String s)
{
int l1 = a.length();
int l2 = s.length();
if(l1 == l2)
for(int i = 0; i > l1; i++)
System.out.print( a.substring(0, 1) + s.substring(0, 1));
}
public static void main(String args[ ])
{
Zippppp sv = new Zippppp("ABC", "123");
System.out.print(sv);
}
}
您当前正在实例化 Zippppp
个实例并作为实例化的副作用进行打印。这不是构造函数的目的,创建一个 static
方法和 return 一个 String
。并使用StringBuilder
。像,
public static String Zippppp(String a, String s) {
StringBuilder sb = new StringBuilder();
if (a != null && s != null && a.length() == s.length()) {
for (int i = 0; i < a.length(); i++) {
sb.append(a.charAt(i)).append(s.charAt(i));
}
}
return sb.toString();
}
然后调用它
System.out.println(Zippppp("ABC", "123"));
我喜欢你的 class 名字。此致
为了真正“return”,你可以实现类似于下面的例子。
Update/Edit:原始答案在下面,因为三种新方法(不关心要压缩的字符串数量)在最上面。
[MultiThreaded
]
要压缩的每个单词都由一个线程处理。为什么?问问自己:为什么不呢???
无聊使事情发生。
每个词都将由自己的线程可爱地处理。由于 AtomicInteger
.
String[] mix =new String[]{"AAAZZZ","100001","BBBWWW","200002","CCCYYY","300003",
"DDDXXX", "400004","EEEWWW","5000005","FFFVVV","600006"};
int strl = mix[0].length(); //entry's length
int nwords = mix.length; //number of strings
char[] zip=new char[strl*nwords]; //the result
AtomicInteger myWord = new AtomicInteger(0);
//returning boolean if want to check some future failed(not here lol)
List<Callable<Boolean>> callables = new ArrayList<>(nwords);
Callable<Boolean> zipYours =
new Callable<Boolean>()
{
public Boolean call()
{
try
{
int mine = myWord.getAndIncrement();
for (int x=0; x < strl; x++)
zip[mine+(nwords*x)]=mix[mine].charAt(x);
}catch(Exception e) {
return false;
}
return true;
}
};
for (int i=0;i<nwords;i++)
callables.add(zipYours);
//one thread - one word - true loef
ExecutorService executor = Executors.newFixedThreadPool(nwords);
executor.invokeAll(callables);
executor.shutdown();
System.out.println(new String(zip));
/*A1B2C3D4E5F6A0B0C0D0E0F0A0B0C0D0E0F0Z0W0Y0X0W0V0Z0W0Y0X0W0V0Z1W2Y3X4W0V6*/
这是必须的吗?当然不是。不过挺好玩的,女朋友叫我做的。
骗人,我没有女朋友。你真的认为如果我有一个我会这样做吗??
[Zip'em all
]
两种不同的方法:
1.直接移动
无论要压缩的字符串数量如何,从 2 到 n 都有效。*这意味着这些方法也是旧方法的替代品,因为您可以调用 getStringsZippedDirectMove("ABC,"123")
或 getStringsZippedDirectMove(yourArray)
.
在这种方法中,每个字符串一次都被完全分配,因此列表中的每个元素只有 accessed/processed 一次。主循环根据数组中元素的数量进行迭代:
public static String getStringsZippedDirectMove(String... mix)
{
if (!goodMix(mix))
return "woloolooO"; //you are a blue monk now
int cn = mix[0].length(), n = mix.length; //cn = 3 | n = 6
char[] zip=new char[cn*n];
for (int i=0; i<n; i++)
for (int x=0; x<cn; x++)
zip[i+(n*x)] = mix[i].charAt(x);
return new String(zip);
}
boolean goodMix(String ... mix)
{
if (mix.length<2)
return false;
for (int i=1; i<mix.length; i++)
if (mix[i].length()!=mix[0].length())
return false;
return true;
}
例如,对于第一个字符串:"AAA
":
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*0)]=mix[0].charAt(0);
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*1)]=mix[0].charAt(1);
zip[i+(n*x)]=mix[i].charAt(x); // zip[0 + (6*2)]=mix[0].charAt(2);
zip[0]=A zip[6]=A zip[12]=A
对于最后一个字符串:“789
”:
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*0)]=mix[5].charAt(0);
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*1)]=mix[5].charAt(1);
zip[i+(n*x)]=mix[i].charAt(x); // zip[5 + (6*2)]=mix[5].charAt(2);
zip[5]=7 zip[11]=8 zip[17]=9
相同的输出:
String[] mix =new String[] { "AAA","123","BBB","456","CCC","789"};
System.out.println(getStringsZippedDirectMove(mix)); //"A1B4C7A2B5C8A3B6C9"
每次迭代都会导致 String 元素的字符完全重定位。
2。从索引开始多次移动 - Holger 风格
受到 Holger 评论的启发
无论要压缩的字符串数量如何,从 2 到 n。*
public String getStringsZippedHolger(String ... mix)
{
if (!goodMix(mix))
return "woloolooO"; //you are a red monk now
char[] zip = new char[mix[0].length()*mix.length];
for (int i=0, j=0; i<mix[0].length(); i++)
for (String s : mix)
zip[j++] = s.charAt(i);
return new String(zip);
}
主循环迭代三次,因为它基于每个文本的长度 (3)。在每次迭代中,它将在 j
标记的索引中的数组中的每个字符串中附加位置 i
处的字符。最后一个计数器在每次分配时递增。
String[] mix =new String[] { "AAA","123","BBB","456","CCC","789"};
System.out.println(getStringsZippedHolger(mix)); // "A1B4C7A2B5C8A3B6C9"
System.out.println(getStringsZippedHolger("HLE","OGR"));
System.out.println(getStringsZippedHolger("IT S","SHBS"," EO "));
原答案块(2串)
Arrays
每次迭代双重赋值
public String getZippppppppppppppppppppppppp(String a, String s) //a -"ABC" s -"123"
{
if (s.length()!=a.length())
return "";
char[] zip=new char[s.length()*2];
for (int i=0; i<s.length(); i++)
{
zip[i*2] = a.charAt(i);
zip[(i*2)+1] = s.charAt(i);
}
return new String(zip); /* "A1B2C3" */
}
遍历任何字符串的长度并按顺序插入每个元素。在迭代期间,这是分配的值:
i = 0 i = 1 i = 2
--------------------------------------------------------
zip[0] = A zip[2] = B zip[4] = C
zip[1] = 1 zip[3] = 2 zip[5] = 3
可怕的油漆:
结果,我们得到:
zip = ['A','1','B','2','C','3']
|||
new String(zip) = "A1B2C3"
注:不爱数组就没有炉石
每次迭代单次赋值
这对迭代逻辑使用了另一种方法,当您可以执行上一个示例所做的操作时,这似乎完全没用。但只是为了好玩。
static String getZipppppppppppppppppppppUsingCharAtThanksElliot(String a, String s)
{ //a -"ABC" s -"123"
if (a.length()!=s.length())
return "";
char[] zip = new char[s.length()*2];
int c=0;
boolean even = false;
for(int i =0; i < (s.length()*2); i++)
{
even =!even;
if (even)
zip[i] = a.charAt(c);
else
{
zip[i] = s.charAt(c);
c++;
}
}
return new String(zip); //--> "A1B2C3"
}
String#subString
:
public String getZippppppppppppppppppppppppp(String a, String s) //a -"ABC" s -"123"
{
if (a.length()!=s.length())
return "";
String line="";
for(int i = 0; i < s.length(); i++)
line += ( a.substring(i*1, (i*1)+1) + s.substring(i*1, (i*1)+1) );
return line; //--> "A1B2C3"
}
可能是性能最差的方法。
String#charAt
请注意 charAt()
,在 Elliot 的回答中正确指出,不适用于此逻辑;它会给你一个数字文本,作为添加它们各自的 unicode 值的结果。它不会附加字符。
使用 charAt()
的替代方法是使用 空字符串解决方法 ,或者像第二个无聊的示例那样创建 char[]
。
public String getZipppppppppppppppppppppUsingCharAtThanksElliot(String a, String s)
{ //a -"ABC" s -"123"
if (a.length()!=s.length())
return "";
String line="";
for(int i = 0; i < s.length(); i++)
line += a.charAt(i) + "" + s.charAt(i) ; //note the empty string
return line; //--> "A1B2C3"
}
不要在字符串上使用 charAt
、substring
- 使用
charAt
和substring
假设String
中的字符位于基本多语言平面 (BMP) - 对于补充平面 (SP) 中的任何字符,这些假设将给出无效字符
使用代码点
- 代码点应成为默认值,任何使用
char
的处理都应弃用 - 使用番石榴
Streams.zip
(这是很长一段时间的测试版,我们可以依赖)
import com.google.common.collect.Streams;
import java.util.stream.Collectors;
class Zippppp {
private final String zipped;
public Zippppp(String a, String b) {
zipped = Streams.zip(a.codePoints().boxed(), b.codePoints()
.boxed(), (x, y) -> new String(Character.toChars(x)) + new String(Character.toChars(y)))
.collect(Collectors.joining());
}
public static void main(String[] args){
System.out.println(new Zippppp("\uD83D\uDE00\uD83D\uDE00\uD83D\uDE00", "123").zipped); // 123
System.out.println(new Zippppp("ABC", "12").zipped); // A1B2
}
}