Java 检查我们是否可以从给定的字母中书写信息的更快方法
我需要编写一个函数,将两个字符串作为输入。一个是我想写的信息,第二个是给我的信。信件是随机排列的。不能保证每个字母出现的次数相同。有些字母可能完全丢失。 该函数应确定我是否可以使用给定的 字母,它应该相应地返回true或false 我对它进行了编码,我认为它非常快,但是我如何改进它呢?记住,带字母的字符串将非常大,而消息将非常短 有没有最快的办法Java 检查我们是否可以从给定的字母中书写信息的更快方法,java,performance,big-o,Java,Performance,Big O,我需要编写一个函数,将两个字符串作为输入。一个是我想写的信息,第二个是给我的信。信件是随机排列的。不能保证每个字母出现的次数相同。有些字母可能完全丢失。 该函数应确定我是否可以使用给定的 字母,它应该相应地返回true或false 我对它进行了编码,我认为它非常快,但是我如何改进它呢?记住,带字母的字符串将非常大,而消息将非常短 有没有最快的办法 import java.util.HashMap; import java.util.Map; import java.util.Random; p
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class LetterBowl {
public static void main(String []args){
String message = generateRandomStringUpToThousandChars();
String bowlWithLetters = generateRandomStringUpToThousandChars();
if(canConstructMessage(message, bowlWithLetters)) {
System.out.println("Message '" + message + "' can be constructed with letters from bowl : " + bowlWithLetters);
}
}
public static boolean canConstructMessage(String message, String letters) {
Map<Character,Integer> letterMap = stringToCharacterMap(letters);
char[] messageList = stringToCharacterList(message);
for(char c : messageList) {
if (!containsLetterAndSubtract(c,letterMap))
return false;
}
return true;
}
// checks if map(bowl) contains char andsubtract one char from map(or removes it if it is last one)
public static boolean containsLetterAndSubtract(char c, Map<Character,Integer> letterMap) {
if(letterMap.containsKey(c)) {
if(letterMap.get(c) > 1) {
letterMap.put(c, letterMap.get(c) - 1);
} else {
letterMap.remove(c);
}
return true;
}
return false;
}
public static char[] stringToCharacterList(String message) {
return message.replaceAll(" ", "").toCharArray();
}
public static Map<Character,Integer> stringToCharacterMap(String s) {
Map<Character,Integer> map = new HashMap<Character,Integer>();
for (char c : s.toCharArray()) {
if(map.containsKey(c))
map.put(c, map.get(c) + 1);
else
map.put(c, 1);
}
return map;
}
public static String generateRandomStringUpToThousandChars(){
char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < random.nextInt(1000); i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
return output;
};
}
import java.util.HashMap;
导入java.util.Map;
导入java.util.Random;
公共类信箱{
公共静态void main(字符串[]args){
String message=generaterandomStringUpthousandChars();
String bowlWithLetters=generaterandomStringUpthousandChars();
if(canConstructMessage(message,bowlWithLetters)){
System.out.println(“Message”“+Message+””可以用bowl中的字母构造:“+bowlWithLetters”);
}
}
公共静态布尔canConstructMessage(字符串消息、字符串字母){
Map letterMap=stringToCharacterMap(字母);
char[]messageList=stringToCharacterList(消息);
for(字符c:messageList){
如果(!containsLetterAndSubtract(c,字母映射))
返回false;
}
返回true;
}
//检查映射(碗)是否包含字符,并从映射中减去一个字符(如果是最后一个字符,则将其删除)
公共静态布尔containsLetterAndSubtract(字符c,映射-字母映射){
if(字母地图容器(c)){
如果(字母图获取(c)>1){
字母地图。放置(c,字母地图。获取(c)-1);
}否则{
字母地图。删除(c);
}
返回true;
}
返回false;
}
公共静态字符[]stringToCharacterList(字符串消息){
返回消息.replaceAll(“,”).toCharArray();
}
公共静态映射stringToCharacterMap(字符串s){
Map Map=newhashmap();
for(char c:s.toCharArray()){
if(图c)
map.put(c,map.get(c)+1);
其他的
图.put(c,1);
}
返回图;
}
公共静态字符串生成器DomStringUpthousandChars(){
char[]chars=“abcdefghijklmnopqrstuvxyz”.toCharArray();
StringBuilder sb=新的StringBuilder();
随机=新随机();
for(int i=0;i
对于大碗大小和较小的味精大小,我发现这会更有效:
公共静态布尔值canConstructMessageSorted(字符串消息、字符串和字母){
int计数器=0;
布尔字母
//sorting
char[] chars = bowlWithLetters.toCharArray();
Arrays.sort(chars);
String sortedBowl = new String(chars);
//sorting
chars = message.toCharArray();
Arrays.sort(chars);
String sortedMsg = new String(chars);
for (int i = 0; i < sortedMsg.length(); i++) {
hasLetter = false;
for( ; counter < sortedBowl.length() ; counter++) {
if(sortedMsg.charAt(i) == sortedBowl.charAt(counter)) {
hasLetter = true;
break;
}
}
if(!hasLetter) return false;
}
return true;
}
//排序
char[]chars=bowlWithLetters.toCharArray();
数组。排序(字符);
String SORTEDBOLL=新字符串(字符);
//分类
chars=message.toCharArray();
数组。排序(字符);
字符串分类DMSG=新字符串(字符);
对于(int i=0;i
您正在以O(message.size+letters.size)操作。这是目前我能计算出的最低最坏情况时间复杂度。说到最快的方法,你总是可以做得更多。例如,定义方法
public static char[] stringToCharacterList(String message)
而且只使用一次在技术上是没有效率的。您可以简单地将该代码体放在canConstructMessage()方法中,保存另一项,使其不会被放置在堆栈上或从堆栈中取出。虽然这是一段很短的时间,但当你说“最快”时,它可能值得一提。对于
字母中的每个字母,从邮件中删除一份。如果消息最终为空,则回答为“是”:
我发现这对于大碗大小和小味精大小更有效:
public static boolean canConstructMessageSorted(String message, String bowlWithLetters) {
int counter = 0;
boolean hasLetter;
//sorting
char[] chars = bowlWithLetters.toCharArray();
Arrays.sort(chars);
String sortedBowl = new String(chars);
//sorting
chars = message.toCharArray();
Arrays.sort(chars);
String sortedMsg = new String(chars);
for (int i = 0; i < sortedMsg.length(); i++) {
hasLetter = false;
for( ; counter < sortedBowl.length() ; counter++) {
if(sortedMsg.charAt(i) == sortedBowl.charAt(counter)) {
hasLetter = true;
break;
}
}
if(!hasLetter) return false;
}
return true;
}
public静态布尔canConstructMessageSorted(字符串消息、字符串和字母){
int计数器=0;
布尔字母;
//分类
char[]chars=bowlWithLetters.toCharArray();
数组。排序(字符);
String SORTEDBOLL=新字符串(字符);
//分类
chars=message.toCharArray();
数组。排序(字符);
字符串分类DMSG=新字符串(字符);
对于(int i=0;i
这些字母一定要用英语吗?不一定。但是英语可以作为例子。这对message=“aaa”,letters=“abcdefgh”不起作用,因为你没有足够的字母“a”来组成信息。@Juka我把这个问题解释为允许重复使用字母,但我认为你是对的(见编辑后的答案)。有没有最快的方法,请记住,我们总是使用小消息字符串和长字母字符串(消息可以是“abc”,字母可以是“sabcjksdafofjifdhsf……最多10000个字符等”)?因此,我们正在寻找最快的最佳方案。还有其他更好的方法吗?@Juka我不知道你对最好的情况感兴趣。通常,您希望改善最坏情况,有时甚至是一般情况。当你谈论贝斯特c
public static boolean canConstructMessage(String message, String letters) {
return letters.chars().boxed().collect(Collectors.toSet())
.containsAll(message.chars().boxed().collect(Collectors.toSet());
}
public static boolean canConstructMessageSorted(String message, String bowlWithLetters) {
int counter = 0;
boolean hasLetter;
//sorting
char[] chars = bowlWithLetters.toCharArray();
Arrays.sort(chars);
String sortedBowl = new String(chars);
//sorting
chars = message.toCharArray();
Arrays.sort(chars);
String sortedMsg = new String(chars);
for (int i = 0; i < sortedMsg.length(); i++) {
hasLetter = false;
for( ; counter < sortedBowl.length() ; counter++) {
if(sortedMsg.charAt(i) == sortedBowl.charAt(counter)) {
hasLetter = true;
break;
}
}
if(!hasLetter) return false;
}
return true;
}