我遇到了扫描仪无法识别特定字符的问题。

huangapple go评论62阅读模式
英文:

I am having issues with the scanner not recognizing certain characters

问题

import java.util.Scanner;
import java.util.TreeSet;

public class setCalculator {
    static Scanner input = new Scanner(System.in);

    public static void main(String[] args) {

        System.out.println("Enter a list of non-negative integers, separated by commas, and enclosed in square brackets. ");
        System.out.println("For example: [1, 2, 3] + [4, 3, 10, 0]. ");

        while (true) {
            System.out.print("\nEnter Sequences: ");
            if (input.hasNext("\n")) {
                break;
            }
            try {
                compute();
            } catch (IllegalArgumentException e) {
                System.out.println("Error in input: " + e.getMessage());
            }
            input.next();
        }

    }

    public static void compute() {

        TreeSet<Integer> setA, setB;  // The two sets of integers.

        setA = readSet();
        if (!input.hasNext("\\+") && !input.hasNext("\\-") && !input.hasNext("\\*"))
            throw new IllegalArgumentException("Expected *, +, or  - after first set.");
        setB = readSet();
        if (input.hasNext("\n"))
            throw new IllegalArgumentException("Extra unexpected input.");
        if (input.hasNext("\\+"))
            setA.addAll(setB);     // Union.
        else if (input.hasNext("\\*"))
            setA.retainAll(setB);  // Intersection.
        else
            setA.removeAll(setB);  // Set difference.

        System.out.print("Value:  " + setA);
    }

    private static TreeSet<Integer> readSet() {
        TreeSet<Integer> set = new TreeSet<Integer>();
        if (!input.hasNext("\\[")) {
            throw new IllegalArgumentException("Expected '[' at start of set.");
        }
        if (input.hasNext("\\[")) {
            input.nextLine();
            return set;
        }
        while (true) {
            // Read the next integer and add it to the set.
            if (!input.hasNextInt())
                throw new IllegalArgumentException("Expected an integer.");
            int n = input.nextInt(); // Read the integer.
            set.add(Integer.valueOf(n));  // (Could have just said set.add(n)!)
            if (input.hasNext("\\]")) {
                break;  // ']' marks the end of the set.
            } else if (input.hasNext("\\,")) {
                input.next(); // Read a comma and continue.
            } else {
                throw new IllegalArgumentException("Expected ',' or ']'.");
            }
        }

        input.next(); // Read the ']' that ended the set.

        return set;
    }
}
英文:

I am new to programming and have never used scanner before. I am having issues with the scanner not recognizing certain characters or at least that is what I think the issue is. The program that I have to make should compute the intersection, union, and set difference of two sets of non-negative integers. The user should input two sets separated by commas, and enclosed in square brackets. For example: [1, 2, 3] + [4, 3, 10, 0]. I was also asked to use TreeSets, and use the appropriate TreeSet method to perform the requested operation on the two sets. At the moment the output that I receive is:

Enter a list of non-negative integers, separated by commas, and enclosed in square brackets.
For example: [1, 2, 3] + [4, 3, 10, 0].

Enter Sequences: [0,1,2,3]+[4,5,6]
Error in input: Expected '[' at start of set.

Any help would be appreciated.

import java.util.Scanner;
import java.util.TreeSet;  
public class setCalculator {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) { 
System.out.println(&quot;Enter a list of non-negative integers, separated by commas, and enclosed in square brackets.  &quot;);
System.out.println(&quot;For example: [1, 2, 3] + [4, 3, 10, 0]. &quot;);
while(true) {
System.out.print(&quot;\nEnter Sequences: &quot;);
if(input.hasNext(&quot;\n&quot;)) {
break;
} try {
compute();
} catch (IllegalArgumentException e) {
System.out.println(&quot;Error in input: &quot; + e.getMessage());
}
input.next();
}
}
public static void compute(){
TreeSet&lt;Integer&gt; setA, setB;  // The two sets of integers.
setA = readSet();
if (! input.hasNext(&quot;\\+&quot;) &amp;&amp; ! input.hasNext(&quot;\\-&quot;) &amp;&amp; ! input.hasNext(&quot;\\*&quot;))
throw new IllegalArgumentException(&quot;Expected *, +, or  - after first set.&quot;);
setB = readSet();
if( input.hasNext(&quot;\n&quot;))
throw new IllegalArgumentException(&quot;Extra unexpected input.&quot;);
if(input.hasNext(&quot;\\+&quot;))
setA.addAll(setB);     // Union.
else if (input.hasNext(&quot;\\*&quot;))
setA.retainAll(setB);  // Intersection.
else
setA.removeAll(setB);  // Set difference.
System.out.print(&quot;Value:  &quot; + setA);
/*
* Start with an empty set.
Read the &#39;[&#39; that begins the set.
Repeat:
Read the next number and add it to the set.
If the next character is &#39;]&#39;:
break.
Read the comma that separates one number from the next.
Read the &#39;]&#39;.
Return the set.
*/
}
private static TreeSet&lt;Integer&gt; readSet() {   	
TreeSet&lt;Integer&gt; set = new TreeSet&lt;Integer&gt;();
if(! input.hasNext(&quot;\\[&quot;)) {
throw new IllegalArgumentException(&quot;Expected &#39;[&#39; at start of set.&quot;);
}
if(input.hasNext(&quot;\\[&quot;)){
input.nextLine();
return set;
}
while (true) {
// Read the next integer and add it to the set.
if (! input.hasNextInt())
throw new IllegalArgumentException(&quot;Expected an integer.&quot;);
int n = input.nextInt(); // Read the integer.
set.add(Integer.valueOf(n));  // (Could have just said set.add(n)!)
if (input.hasNext(&quot;\\)&quot;))
break;  // &#39;]&#39; marks the end of the set.
else if (input.hasNext(&quot;\\,&quot;))
input.next(); // Read a comma and continue.
else
throw new IllegalArgumentException(&quot;Expected &#39;,&#39; or &#39;]&#39;.&quot;);
}
input.next(); // Read the &#39;]&#39; that ended the set.
return set;
}
}

答案1

得分: 1

问题可能在于你对 Scanner.hasNext() 的使用。特别是在 if(input.hasNext("\\[")){ 这一部分。如果我没有误解,这将检查完整的标记,而不仅仅是 "["。

总体而言,你的方法使问题变得过于复杂。我个人不会通过 Scanner 处理整个任务。更容易的方法是简单地从 Scanner 中获取输入,然后在获取的字符串上进行输入验证。

以下是一个简短的代码片段,它会从 Scanner 中获取输入,将其保存在一个字符串中,并从提供的字符串中解析出 Set。(但肯定有更有效的解决方案)

编辑:

public static void main(String args[]) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Enter the sequence:");
    // 读取整个输入
    String input = scanner.nextLine();
    // 找到运算符
    String op = findOperator(input);
    // 在 "+" 上拆分字符串
    String[] sets = input.split("\\" + op);
    if (sets.length != 2) {
        // 错误输入,抛出异常
        return;
    }
    TreeSet<Integer> setA = parseSet(sets[0]);
    TreeSet<Integer> setB = parseSet(sets[1]);
    TreeSet<Integer> resultSet = computeResultSet(setA, setB, op);
    System.out.println(resultSet);
}

private static String findOperator(String input) {
    char[] operators = { '+', '-', '*' };
    for (char c : operators) {
        if (input.indexOf(c) != -1) {
            return "" + c;
        }
    }
    // 未找到运算符 -> 错误输入 -> 异常处理
    return "";
}

private static TreeSet<Integer> parseSet(String input) {
    TreeSet<Integer> outputSet = new TreeSet<Integer>();
    // 去除空格
    input = input.trim();
    // 检查输入是否具有正确的格式
    if (!input.startsWith("[") || !input.endsWith("]")) {
        // 错误输入,抛出异常
        return outputSet;
    }
    // 去除括号
    input = input.substring(1, input.length() - 1);
    // 将整数添加到集合中
    String[] digits = input.split(",");
    for (String singleDigit : digits) {
        outputSet.add(Integer.parseInt(singleDigit.trim()));
    }
    return outputSet;
}

private static TreeSet<Integer> computeResultSet(TreeSet<Integer> setA, TreeSet<Integer> setB, String op) {
    TreeSet<Integer> resultSet = new TreeSet<Integer>();
    if (op.equals("+")) {
        setA.addAll(setB);
    } else if (op.equals("-")) {
        setA.removeAll(setB);
    } else if (op.equals("*")) {
        setA.retainAll(setB);
    }
    resultSet = setA;
    return resultSet;
}

输入:

Enter the sequence:
[1,2,3] - [2,3]

输出:

[1]
英文:

The issue probably lies in your usage of Scanner.hasNext(). Especially on if(input.hasNext(&quot;\\[&quot;)){. If I'm not mistaken, this will check against the complete token, which is clearly more than only the "[".

Overall, your approach is overcomplicating the issue. I personally would not work through the whole task with the scanner. It's easier to simply take the input from the scanner and then do the input validation on the retrieved String.

This short snippet will take the input from the scanner, save it in a String and parse the Sets from the provided String. (But there is definitely a more efficient solution possible)

Edit:

public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
System.out.println(&quot;Enter the sequence:&quot;);
// read the whole input
String input = scanner.nextLine();
// find the operator
String op = findOperator(input);
// split the String on &quot;+&quot;
String[] sets = input.split(&quot;\\&quot; + op);
if (sets.length != 2) {
// raise exception for incorrect input
return;
}
TreeSet&lt;Integer&gt; setA = parseSet(sets[0]);
TreeSet&lt;Integer&gt; setB = parseSet(sets[1]);
TreeSet&lt;Integer&gt; resultSet = computeResultSet(setA, setB, op);
System.out.println(resultSet);
}
private static String findOperator(String input) {
char[] operators = { &#39;+&#39;, &#39;-&#39;, &#39;*&#39; };
for (char c : operators) {
if (input.indexOf(c) != -1) {
return &quot;&quot; + c;
}
}
// operator not found -&gt; wrong input -&gt; exception handling
return &quot;&quot;;
}
private static TreeSet&lt;Integer&gt; parseSet(String input) {
TreeSet&lt;Integer&gt; outputSet = new TreeSet&lt;Integer&gt;();
// remove whitespaces
input = input.trim();
// check if the input has the correct format
if (!input.startsWith(&quot;[&quot;) || !input.endsWith(&quot;]&quot;)) {
// exception for incorrect input
return outputSet;
}
// remove the braces
input = input.substring(1, input.length() - 1);
// add the integers to the set
String[] digits = input.split(&quot;,&quot;);
for (String singleDigit : digits) {
outputSet.add(Integer.parseInt(singleDigit.trim()));
}
return outputSet;
}
private static TreeSet&lt;Integer&gt; computeResultSet(TreeSet&lt;Integer&gt; setA, TreeSet&lt;Integer&gt; setB, String op) {
TreeSet&lt;Integer&gt; resultSet = new TreeSet&lt;Integer&gt;();
if (op.equals(&quot;+&quot;)) {
setA.addAll(setB);
} else if (op.equals(&quot;-&quot;)) {
setA.removeAll(setB);
} else if (op.equals(&quot;*&quot;)) {
setA.retainAll(setB);
}
resultSet = setA;
return resultSet;
}

Input:

Enter the sequence:
[1,2,3] - [2,3]

Output:

[1]

huangapple
  • 本文由 发表于 2020年9月30日 15:58:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/64133282.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定