【问题标题】:checking for the correct number of characters in a java string [closed]检查java字符串中正确的字符数[关闭]
【发布时间】:2012-08-04 06:08:59
【问题描述】:

我正在尝试计算 java 字符串中出现的字符数。

例如:

给定扑克手牌 6s/3d/2H/13c/Ad

/ 字符出现了多少次? = 4

用户可以输入不同数量的牌变量,因此硬编码检查出现次数的方法是行不通的。

分隔符可以是以下任何一种: - / 空格(一只手只允许使用一种分隔符类型)。 所以我需要能够检查是否有任何一个分隔符出现了 4 次,否则给出了不正确的格式。

这是一些 java 代码,可以更好地了解我正在尝试做什么:

    String hand = "6s/1c/2H/13c/Ad";
    System.out.println("Original hand: " + hand);

    // split the hand string into individual cards
    String[] cards = hand.split(hand);

    // Checking for separators
    // Need to check for the correct number of separators
    if(hand.contains("/")){
        cards = hand.split("/");
    } else if (hand.contains("-")){
        cards = hand.split("-");
    } else if (hand.contains(" ")){
        cards = hand.split(" ");
    } else {
        System.out.println("Incorrect format!");

    }

任何帮助都会很棒!

这也是一个学校项目/家庭作业。

编辑 1--------------------------------------------------------- ------------

好的,根据你的建议,这是我的代码

    String hand = "6s 1c/2H-13c Ad";
    System.out.println("Original hand: " + hand);

    // split the hand string into individual cards
    String[] cards = hand.split("[(//\\-\\s)]");

    if (cards.length != 5) {
        System.out.println("Incorrect format!");    
    } else {

        for (String card : cards) {
            System.out.println(card);
        }
    }

上面给定的手牌格式不正确,因为用户只能对给定的手牌使用一种类型的分隔符。例如:

  • 6s/1c/2H/13c/Ad - 正确
  • 6s-1c-2H-13c-Ad - 正确
  • 6s 1c 2H 13c 广告 - 正确

如何确保用户只使用一种分隔符??

为到目前为止的答案干杯!

编辑 2 ------------------------------------------

所以使用嵌套的 if 语句,我的代码现在看起来像这样:

    String hand = "6s/1c/2H/13c/Ad";
    System.out.println("Original hand: " + hand);

    // split the hand string into individual cards

    if(hand.contains("/")){
        String[] cards = hand.split("/");
        if(cards.length != 5){
            System.out.println("Incorrect format! 1");
        } else {
            for (String card : cards) {
                System.out.println(card);
            }
        }

    } else if(hand.contains("-")){
        String[] cards = hand.split("-");
        if(cards.length != 5){
            System.out.println("Incorrect format! 2");
        } else {
            for (String card : cards) {
                System.out.println(card);
            }
        }

    } else if(hand.contains(" ")){
        String[] cards = hand.split(" ");
        if(cards.length != 5){
            System.out.println("Incorrect format! 3");
        } else {
            for (String card : cards) {
                System.out.println(card);
            }
        }
    } else {
        System.out.println("Incorrect format! 4");
    }

这种方式按预期工作,但很丑!

任何建议都会非常高兴。

【问题讨论】:

  • 这是家庭作业,只是一个提示。 split 方法允许使用正则表达式,这可能会解决您的问题。请看docs.oracle.com/javase/6/docs/api/java/util/regex/…
  • 谢谢。我一直在尝试使用正则表达式,但如果给定的手被改变,它似乎不起作用。例如,用户可以输入 AS/13D/JS/13S/AD,这会改变分隔符出现的位置。但这么说可能是我做正则表达式的方式。干杯。
  • @user1575658 你试过什么正则表达式?
  • 发布您的正则表达式,然后让 SO 为您提供帮助。
  • 这是我的正则表达式 [(//\\-\\s)]

标签: java arrays string split


【解决方案1】:

在不泄露答案的情况下,您希望将分隔符指定为 split,以便返回的字符串数组如下所示:

cards[0] = "6s"
cards[1] = "1c"
cards[2] = "2H"
.
.
.

在您的特定手牌字符串中,您可以为每张卡片使用方便的分隔符来实现此目的...

【讨论】:

    【解决方案2】:

    我在第一个问题编辑之前写了这个,所以我回答的是原始问题而不是它的附录问题。

    documentation on String.split 中,不清楚空字符串是否算作子字符串。请注意"--".split("-").length == 0。该问题可能隐含地保证两个或多个字符分隔分隔符,但这是一个冒险的假设,并且 Java 的 String.split 会出现问题。

    这是一个部分更简单的实现:

        char[] delims = {'/', ' ', '-'};
        int result = 0;
        for (char delim : delims) {
            for (int i = 0; i < hand.length(); i++) {
                if (hand.charAt(i) == delim) {
                    ++result;
                }
            }
        }
    

    下面是完整的代码,带有用于家庭作业的编辑 cmets。

    interface Counter {
        int count(String hand);
    }
    class FirstCounter implements Counter {
        public int count(String hand) {
            String[] cards = hand.split(hand);
            if(hand.contains("/")){
                cards = hand.split("/");
            } else if (hand.contains("-")){
                cards = hand.split("-");
            } else if (hand.contains(" ")){
                cards = hand.split(" ");
            } else {
                // Prefer to fail fast unless your requirement
                // really is to only print "incorrect format"
                //System.out.println("Incorrect format!");
                throw new RuntimeException("Incorrect format!");
            }
            if (hand.endsWith("-") || hand.endsWith("/") || hand.endsWith(" ")) {
                return cards.length;
            }
            return cards.length - 1;
        }    
    }
    class SecondCounter implements Counter {
        public int count(String hand) {
            char[] delims = {'/', ' ', '-'};
            int result = 0;
            for (char delim : delims) {
                for (int i = 0; i < hand.length(); i++) {
                    if (hand.charAt(i) == delim) {
                        ++result;
                    }
                }
            }
            if (result == 0) {
                // This is a hack or inconsistent with requirements,
                // but necessary to match original posted code behavior
                throw new RuntimeException("Incorrect format!");
            }
            return result;
        }
    }
    class Main {
        private static int testCount = 0;
    
        static void realAssert(boolean condition) {
            if (!condition) {
                throw new AssertionError("Java has no real assert");
            }
        }
    
        static void test(Counter counter) {
            ++testCount;
            try {
                realAssert(counter.count("6s/3d/2H/13c/Ad") == 4);
                realAssert(counter.count("6s-3d-2H-13c-Ad") == 4);
                realAssert(counter.count("6s 3d 2H 13c Ad") == 4);
                // Don't forget boundary conditions
                realAssert(counter.count("6s-3d-2H-13c-") == 4);
                realAssert(counter.count("6s/3d/2H/13c/") == 4);
                realAssert(counter.count("6s 3d 2H 13c ") == 4);
                realAssert(counter.count("-6s-3d-2H-13c-") == 5);
                realAssert(counter.count("/6s/3d/2H/13c/") == 5);
                realAssert(counter.count(" 6s 3d 2H 13c ") == 5);
                realAssert(counter.count("--") == 2);
                // Remember to test error conditions
                try {
                    counter.count("foobar");
                    realAssert(false);
                } catch (RuntimeException e) {
                    // Catching RuntimeException is normally bad
                    // done only as example.
                    // Also normally bad, this is an empty catch
                    // block. These are sometimes useful, but always
                    // at least add a comment that explains that this
                    // catch block really should be empty, in this case
                    // because the test was meant to throw an Error.
                }
                try {
                    counter.count("foo/bar-baz");
                    // Left as exercise for reader, based on question
                    // it is possible this should be disallowed.
                    //realAssert(false);
                } catch (RuntimeException e) {
                    // Ditto above, intentionally empty catch
                }
                System.out.println("Test " + testCount + " succeeded");
            }
            catch (Error e) {
                // XXX: Don't catch Error in non-example code
                System.out.println("Test " + testCount + " failed");
                /* Normally don't use printStackTrace either */
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            test(new FirstCounter());
            test(new SecondCounter());
        }
    }
    

    仅用于教育,正则表达式方法可能很好。整个解决方案只需要一行 Ruby,hand.split(/[\-\/ ]/, -1).length - 1

    【讨论】:

      【解决方案3】:

      使用regex

      例如:

      String reg = new String();
      String s = "hjhjhkello/hi"; 
      Pattern pattern = Pattern.compile("[(/-\\\\s)]");  // Will find for / or - or space
      Matcher matcher = pattern.matcher(s);
      
      while(matcher.find()){
      
       reg = matcher.group());
      
      }
      
      
      String[] arr = hand.split(reg);
      

      【讨论】:

      • 我认为我们不应该为homework 问题提供完整的答案...提示就足够了。
      【解决方案4】:

      hand.split(hand) 不起作用。正如@home 所说,您应该将输入字符串拆分为正则表达式。了解正则表达式不必(也不应该)匹配整个输入字符串——它应该匹配任何单独的分隔符。这就是 String.split 在传递正则表达式时的工作方式——正则表达式匹配的每个位置都被视为分隔符,匹配之间的部分作为数组返回。

      所以:尝试编写一个匹配任何一个分隔符的正则表达式。然后,检查返回的数组是否包含正确数量的元素。如果数组名为hand,则可以使用hand.length

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-03
        • 2017-04-07
        相关资源
        最近更新 更多