在Java中如何迭代遍历字符串?

8
public static Boolean cmprStr( String s1, String s2 )
{
    // STUFF
}

我希望能够遍历s1,以确保s1中的每个字符都包含在s2中。

区分大小写还是不区分大小写? - Srinivas Reddy Thatiparthy
2
你的意思是每个字符都出现在两个字符串中,还是它们是相同的字符串? - keyboardP
1
s1 中的每个字符都出现在 s2 中。 - Shamoon
9个回答

11
  for(char c: s1.toCharArray()){
     if(s2.indexOf(c) == -1){
           return false;
     }
  }
  return true;

假设

  s1 = "aabb";
  s2 = "ccddaannbbss";

将返回 true。


3
我认为使用toCharArray迭代字符串会复制该字符串。这可能比简单的for循环效率要低。 - ceving
这会创建一个不必要的额外对象。 - darkknight444

11
public static Boolean cmprStr( String s1, String s2 )
{
    for (int i = s1.length() - 1; i >= 0; --i) {
         if (s2.indexOf(s1.charAt(i)) == -1) {
             return Boolean.FALSE;
         }
    }
    return Boolean.TRUE;
}

4
@Jim - 我没有看到作业标签。@sjr - 我知道。我看到你发布了一个O(n+m)的解决方案。从渐进复杂度来看,这更好,但我想知道字符串需要多长才能在实际中比较好。像你构造HashSet这样的过程中有很多开销。 - Ted Hopp
1
没有getChar这个方法,但是有charAt方法。 - Dejell
@Odelya - 很好的发现,现在已经修复了。我已经用太多种语言编程了。 - Ted Hopp

10
length()

将会给你一个字符串的长度

charAt( someIndex)

这将给你指定位置上的字符,因此你可以遍历第一个字符串。

indexOf( achar )

将返回所查找字符在字符串中的位置,如果不存在则返回-1。因此,您应该能够在第二个字符串中查找第一个字符串中的每个字符。


2
提供必要的部分而不是完成他的家庭作业,这是一个好习惯。 - user395760

3

其他所有答案的时间复杂度都是O(n^2)。这里有一种使用Google Guava的方法,时间复杂度为线性(即O(n)):

  public static boolean cmprStr(String s1, String s2) {
    Set<Character> desiredCharacters = Sets.newHashSet(Lists.charactersOf(s2));
    return Sets.difference(Sets.newHashSet(Lists.charactersOf(s1)), desiredCharacters).isEmpty();
  }

2
将渐近复杂度降至O(n+m)是一个好的选择,这对于非常长的字符串来说尤其如此。只需构建一个HashSet并迭代第二个字符串的字符以查找集合成员,就可以减少开销。此外,从启发式角度来看,先对较短的字符串进行哈希处理,然后再迭代较长的字符串也是有意义的。 - Ted Hopp

2
Set<Character> charsInS1 = new HashSet<Character>();
for (int i = 0; i < s1.length(); i++) {
  charsInS1.add(s1.charAt(i));
}
for (int i = 0; i < s2.length(); i++) {
  charsInS1.remove(s2.charAt(i));
}
return charsInS1.isEmpty();

这个算法的复杂度为 O(n+m)... 使用 indexOf 来得出答案的复杂度为 O(n*m)。当然,这会暂时使用一些额外的内存。

这不仅使用了一点内存,而且在构建HashSet时还有相当多的额外处理开销。我敢打赌,对于非常短的字符串,这比O(n*m)解决方案(正确实现时)表现更差。我想知道这种方法需要多长的字符串才能达到平衡点。 - Ted Hopp

1
为什么不直接使用“equals”方法呢?
Boolean b = s1.equals(s2);

或者s1.compareTo(s2)会给你负数、零、正数的值。零表示相等。阅读http://j.mp/mONeBc。 - ahmet alp balkan
1
这段代码没有实现问题要求的功能,即检查s1中的每个字符是否也在s2中出现。按照问题描述,它不应考虑字符出现的顺序或次数,但这段代码两者都考虑了。 - ColinD
1
除非我漏掉了什么(毕竟有五个人投票支持),否则 OP 不想检查字符串是否相等,而是想检查“对于 s1 中的每个字符 c:c 是否在 s2 中”。在我意识到自己错过了什么之前,先给负一分。 - user395760
啊!好的,抱歉让你感到困惑了! - jlink

0

根据我的理解,问题应该是这样的。

//for each character in s1
  //if s2 does not contain character return false

//return true

for(int i = 0; i < length s1; i++){
  if(!s2.contains(String.valueOf(s1.charAt(i)))){
    return false;
  }
}
return true;

这个函数验证了s1中的每个字符都在s2中出现过。它不关心顺序,也不关心数量,因此不是一个等值方法。

递归:

public static Boolean cmprStr( String s1, String s2 )
{
  if(s1.length() == 0 )
  {
    return true; 
  }
  if(!s2.contains(s1.substring(0,1)))
  {
    return false;
  }
  return cmprStr(s1.substring(1), s2);
}

0

在Java中,每个String也是一个CharSequence。因此,您可以使用简单的for循环轻松迭代String

int n = s.length();
for (int i = 0; i < n; ++i) {
    char c = s.charAt(i);
    ...
}

0
// Here's some code I wrote to find CG ratio in a gene     
public double findCgRatio(String gene)
        {
            double cCount =0.0; 
            double gCount =0.0; 
            gene = gene.toLowerCase(); 
            for(char character : gene.toCharArray())
            {
                if(character == 'c')
                {
                    cCount++; 
                }
                else if(character == 'g')
                {
                    gCount++; 
                }

            }
            System.out.println("CG Ratio was :" + (cCount/gCount) );  
            return cCount/gCount;  // cgRatio 
        }

请添加一些解释。 - Ishita Sinha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接