When I run the code below, why does it throw this error?
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at GuessNumber.main(GuessNumber.java:35)
This is my code, thank you:
public class GuessNumber {
public static void main(String[] args) {
int[][] num = new int[5][16];
int[] len = new int[5];
char[] bit;
for (int i = 1; i <= 32; i++) {
bit = ToBinary(i);
//bit的大小为5:把二进制数存储到数组中num
for (int j = 0; j < bit.length; j++) {
if (bit[j] == '1') {
//11000
num[j][len[j]++] = i;
}
}
}
Random r = new Random((new Date()).getTime());
int numRoad = r.nextInt(31);
bit = ToBinary(numRoad);
String cardRand = "";
for (int i = 0; i < bit.length; i++) {
if (bit[i] == '1') {
cardRand = cardRand + (i + 1) + ",";
}
}
System.out.println("在卡片" + cardRand + "上的数字是:");
System.out.println("请玩家输入猜测数字:");
Scanner c = new Scanner(System.in);
int number = c.nextInt();
if (number == numRoad) {
System.out.println("恭喜您,猜对了.");
} else {
System.out.println("对不起!猜错了,该数应该为:" + numRoad);
}
}
/**
* 将十进制数转成二进制数
*
* #param i
* #return
*/
public static char[] ToBinary(int c) {
char[] bit = new char[5];
String a = Integer.toBinaryString(c);
bit = a.toCharArray();
char temp;
for (int i = 0; i < bit.length / 2; i++) {
temp = bit[i];
bit[i] = bit[bit.length - 1 - i];
bit[bit.length - 1 - i] = bit[i];
}
return bit;
}
}
Most likely because the Scanner expected an integer value and found something else. The exception is a result of your actual input at the console.
Looks like you see a binary number (10011) and have to enter the decimal value (19)
Javadoc to the rescue:
Throws:
InputMismatchException - if the next token does not match the
Integer regular expression, or is out of range
You probably don't enter a valid integer whan asked for it by your program.
Related
public class Binar{
public static void main(String[] args){
int num = 7;
long Binary = cBtD(num);
System.out.printf("%d numri decimal = %d binar" , num, Binary);
}
public static long cBtD(int num){
long BinaryNumber = 0;
int i = 0;
long reminder;
while(num > 0){
reminder = num % 2;
num /= 2;
++i;
}
for (int j = i - 1; j >= 0; j--) {
System.out.print(BinaryNumber[j]);
}
return BinaryNumber;
}}
and i have this error and it says "array required, but long found" and "System.out.print(BinaryNumber[j]);"
Reason behind this error is, you have defined BinaryNumber variable as long and it is not an array. But you are trying to access it like an array. Please check my modified answer below:
public class Binar {
public static void main(String[] args) {
int num = 7;
String Binary = cBtD(num);
System.out.printf("%d numri decimal = %s binar", num, Binary);
}
public static String cBtD(int num) {
String BinaryNumber = "";
long reminder;
if (num == 0) {
return "0";
}
while (num > 0) {
reminder = num % 2;
BinaryNumber = String.valueOf(reminder).concat(BinaryNumber);
num /= 2;
}
return BinaryNumber;
}
}
That error occurred because you defined BinaryNumber's type 'long' and you wanted use it as an array.
I change it a bit, try it:
public class Binar {
public static void main(String[] args) {
int num = 7;
int[] binaryArray = cBtD(num);
String numbers = "";
for (int aBinaryArray : binaryArray)
numbers += aBinaryArray;
System.out.printf("%d numri decimal = %d binar" , num, Integer.parseInt(numbers));
}
private static int[] cBtD(int num){
int i = 0;
int temp[] = new int[7];
int binaryNumber[];
while (num > 0) {
temp[i++] = num % 2;
num /= 2;
}
binaryNumber = new int[i];
int k = 0;
for (int j = i - 1; j >= 0; j--) {
binaryNumber[k++] = temp[j];
}
return binaryNumber;
}
}
Or you can simply use these methods to convert decimal to binary:
Integer.toBinaryString();
Or this:
Integer.toString(n,2);
All numbers are inherently binary. But whether you display them in binary or hex or octal is simply a matter of representation. Which means you want to print them as a string. Even when you do the following:
int v = 123;
System.out.println(v); // v is printed as a decimal string.
So to convert them to a binary string, just prepend the remainders to the string after dividing by two (via the remainder operator).
int n = 11;
String s = "";
s = (n%2) + s; // s = "1"
n/=2; // n == 5
s = (n%2) + s; // s = "11"
n/=2 // n == 2
s = (n%2) + s; // s = "011";
n/=2 // n == 1
s = (n%2) + s; // s = "1011";
n/=2; // n == 0
n == 0 so your done.
return s and print it.
I have this assignment for my university https://cs1331.gitlab.io/fall2018/hw2/hw2-source-model.html. I wrote the code but when I run the program I get this message at the console :
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 2
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3107)
at java.base/java.lang.String.substring(String.java:1873)
at homework1.SourceModel.main(SourceModel.java:127)
Here is my code for this assignment with comments :
package homework1;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class SourceModel {
//initialize variables so they can be accessed everywhere
private String modelName;
private int[][] characterCount;
private double[] rowCount;
private double[][] probability;
/**
*
* #param name takes the name of the corpus
* #param fileName takes the filesName of corpus
*/
public SourceModel(String name, String fileName) {
modelName = name;
characterCount = new int[26][26];
rowCount = new double[26];
probability = new double[26][26];
System.out.println("Training " + name + "model...");
try {
Scanner scan = new Scanner(new File(fileName));
String temp = "";
//append all of the text
while (scan.hasNext()) {
temp += scan.next();
}
//only keeps the letters and makes them lowercase
temp = temp.replaceAll("[^A-Za-z]+", "").toLowerCase();
System.out.println(temp);
//iterates trough each letter then puts the letters
//sequence to the respective row and column
for (int i = 0; i < (temp.length() - 1); i++) {
char firstLetter = temp.charAt(i);
char secondLetter = temp.charAt(i + 1);
//index based on ASCII values
characterCount[(int) firstLetter - 97][(int) secondLetter - 97]++;
rowCount[(int) firstLetter - 97]++;
}
//calculates the probability by dividing the count
//by the total counts in each row
for (int i = 0; i < probability.length; i++) {
for (int j = 0; j < probability[i].length; j++) {
if (rowCount[i] == 0) {
rowCount[i] = 0.01;
}
probability[i][j] = (((double) characterCount[i][j]) / rowCount[i]);
if (probability[i][j] == 0) {
probability[i][j] = 0.01;
}
}
}
System.out.println("done");
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
*
* #return a string which contains the name
*/
public String getName() {
return modelName;
}
/**
* #return a string with the matrix
*/
public String toString() {
String matrix = "";
matrix += "";
for (int i = 97; i < 123; i++) {
matrix += " ";
matrix += (char) i;
}
matrix += ("\n");
for (int i = 0; i < probability.length; i++) {
matrix += ((char) (i + 97) + " ");
for (int j = 0; j < probability[i].length; j++) {
matrix += String.format("%.2f", probability[i][j]);
matrix += ("");
}
matrix += "\n";
}
return matrix;
}
/**
*
* #param test a set of letters to test
* #return the probability for the word
*/
public double probability(String test) {
test = test.replaceAll("[^A-Za-z]+", "").toLowerCase();
double stringProbability = 1.0;
for (int i = 0; i < test.length() - 1; i++) {
int firstIndex = (int) (test.charAt(i)) - 97;
int secondIndex = (int) (test.charAt(i + 1)) - 97;
stringProbability *= probability[firstIndex][secondIndex];
}
return stringProbability;
}
/**
*
* #param args the command line arguments
*/
public static void main(String[] args) {
SourceModel[] models = new SourceModel[args.length - 1];
for (int i = 0; i < args.length - 1; i++) {
models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);
}
System.out.println("Analyzing: " + args[args.length - 1]);
double[] normalizedProbability = new double[args.length - 1];
double sumProbability = 0;
for (int i = 0; i < args.length - 1; i++) {
sumProbability += models[i].probability(args[args.length - 1]);
}
//normalize the probability in respect to the values given
for (int i = 0; i < normalizedProbability.length; i++) {
normalizedProbability[i] = models[i].probability(args[args.length - 1]) / sumProbability;
}
int highestIndex = 0;
for (int i = 0; i < args.length - 1; i++) {
System.out.print("Probability that test string is");
System.out.printf("%9s: ", models[i].getName());
System.out.printf("%.2f", normalizedProbability[i]);
System.out.println("");
if (normalizedProbability[i] > normalizedProbability[highestIndex]) {
highestIndex = i;
}
}
System.out.println("Test string is most likely " + models[highestIndex].getName() + ".");
}
}
Others have already pointed this out, but for this line:
models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);
the substring method is apparently causing the problem because indexOf returns -1 if the . isn't found.
In this case, though, the code actually isn't the problem, since the assignment states that you can assume that the file names are of the form <source-name>.corpus. That being said, really, all of the command line parameters should have a . in them, so this shouldn't be happening.
I'd check to see what command line parameters you're passing. One guess I have is that you might have a file name with a space in it or something. For example, if you passed English GB.corpus, then this would show up as 2 separate arguments (one of which doesn't have a .).
Edit: As #Pshemo pointed out in the comments, if you have a file name that has a space in it, you can just put it in quotes so that it'll be interpreted as a single command line parameter - for example, instead of English GB.corpus, write "English GB.corpus". That'll prevent the exception.
In your main method, you have:
args[i].indexOf(".")
The dot (.) is not found so it returns -1.
You try to create a substring:
models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);
But since args[i].indexOf(".") is invalid, it throws an exception.
What you can do is check if the dot (.) exists, if yes continue:
if(args[i].contains(".")){
models[i] = new SourceModel(args[i].substring(0, args[i].indexOf(".")), args[i]);
}
My code tries to implement an algorithm to
take user input for two integer numbers and an operand + or - from the console,
store those numbers digit by digit in an int[50], representing negative ones in ten's complement format,
implement (decimal) digit-by-digit add/subtract operations,
print the result in decimal format without leading zeroes.
However, in my current implementation there are two problems
When adding 99 + 9999, the printed result is 01098 instead of the expected 010098.
When subtracting 99 - 9999, I get an ArrayIndexOutOfBoundsException: 50 instead of the expected result -09900.
import java.util.*;
public class Program9 {
public static String getOperand() {
Scanner scan = new Scanner(System.in);
String stringOfInteger;
System.out.print("Please enter an integer up to 50 numbers: ");
stringOfInteger = scan.nextLine();
return stringOfInteger;
}
public static int[] convert(String operand) {
int[] integer = new int[50];
char ch;
int position = operand.length() - 1;
for (int i = integer.length - 1; i >= 0; i--) {
if (position >= 0)
ch = operand.charAt(position--);
else
ch = 0;
if (ch >= '0' && ch <= '9') {
integer[i] = ch - '0';
} else {
integer[i] = 0;
}
}
return integer;
}
public static int[] add(int[] operand1, int[] operand2) {
int[] result = new int[operand1.length];
int carry = 0;
for (int i = operand1.length - 1; i >= 0; i--) {
result[i] = operand1[i] + operand2[i] + carry;
if (result[i] / 10 == 1) {
result[i] = result[i] % 10;
carry = 1;
} else
carry = 0;
}
return result;
}
public static int[] complement(int[] operand) {
int[] result = new int[operand.length];
for (int i = operand.length - 1; i >= 0; i--)
result[i] = 9 - operand[i];
return result;
}
public static int[] add1(int[] operand) {
int[] result = new int[50];
result[49] = 1;
for (int i = result.length - 2; i >= 0; i--)
result[i] = 0;
return result;
}
public static int[] negate(int[] operand) {
return add(add1(operand), complement(operand));
}
public static void print(int[] result, String operation) {
if (operation.charAt(0) == '+')
System.out.print("The subtotal of the two integer = ");
else if (operation.charAt(0) == '-')
System.out.print("The substraction of the two integers = ");
if (result[0] == 9) {
result = negate(result);
System.out.print("-");
for (int i = 0; i < result.length; i++) {
if (result[i] == 0 && result[i + 1] == 0)
continue;
else
System.out.print(result[i]);
}
} else
for (int i = 0; i < result.length; i++) {
if (result[i] == 0 && result[i + 1] == 0)
continue;
else
System.out.print(result[i]);
}
System.out.println();
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int[] result = new int[50];
String string1 = getOperand();
String string2 = getOperand();
int[] integer1 = convert(string1);
int[] integer2 = convert(string2);
String operation;
System.out.print("Please enter which operation will be used (+ or -): ");
operation = scan.nextLine();
if (operation.charAt(0) == '+')
add(integer1, integer2);
else if (operation.charAt(0) == '-')
integer2 = negate(integer2);
result = add(integer1, integer2);
System.out.println(Arrays.toString(integer1));
System.out.println(Arrays.toString(integer2));
System.out.println(Arrays.toString(add(integer1, integer2)));
print(result, operation);
}
}
Okay, after so much discussion and so many issues with your code I have totally revised your original code because you said you wanted to learn more. Among other improvements I have done the following changes:
Meaninfgul class name
Meaningful method and parameter names
Convert repeated and often used constants like 50 and the array representation of the number 1 (needed for negation) into static final members for clean code reasons (documentation, easy change in one place, meaningful names), runtime optimisation).
Extend the code to permit negative integers as operands
Added validation patterns for user input. E.g. now the maximum number length is checked in order to avoid an array overflow.
Avoid numeric overflows during calculation by making the array bigger than the maximum number of digits permitted for user input (see source code comments)
Add retry loops with error handling for operand and operator input, extract console handling into one parametrised method.
Simplify code by removing unnecessary checks because user input is already validated before converting it into an int[].
Make debug output optional
package de.scrum_master.stackoverflow;
import java.util.Arrays;
import java.util.Scanner;
import java.util.regex.Pattern;
public class TensComplementArithmetic {
// Print debug messages?
private static final boolean DEBUG = true;
// Maximum length for numbers entered by a user
// (number of digits excluding the optional +/- sign)
private static final int MAX_NUMBER_LENGTH = 50;
// Array must have one additional element for the sign and
// one more to avoid overflows when adding big negative numbers
private static final int ARRAY_LENGTH = MAX_NUMBER_LENGTH + 2;
// Scanner for console input handling
private static final Scanner INPUT_SCANNER = new Scanner(System.in);
// Regex pattern for positive/negative integer number format verification incl. length check
private static final Pattern INTEGER_PATTERN = Pattern.compile("[+-]?[0-9]{1," + MAX_NUMBER_LENGTH + "}");
// Regex pattern for operator verification (currently only "+"/"-" allowed)
private static final Pattern OPERATOR_PATTERN = Pattern.compile("[+-]");
// The number 1 is always needed for converting a 9's into a 10's complement
// during negation, so we define it as a reusable constant
private static final int[] NUMBER_ONE;
static {
// Initialise constant carrying array representation for number 1
NUMBER_ONE = new int[ARRAY_LENGTH];
NUMBER_ONE[ARRAY_LENGTH - 1] = 1;
}
public static String readConsoleInput(String prompt, Pattern validationPattern, String errorMessage) {
String input = null;
while (input == null) {
System.out.print(prompt + ": ");
if (INPUT_SCANNER.hasNext(validationPattern))
input = INPUT_SCANNER.next(validationPattern);
else {
INPUT_SCANNER.nextLine();
System.out.println(errorMessage);
}
}
return input;
}
public static String getOperand(String operandName) {
return readConsoleInput(
"Operand " + operandName,
INTEGER_PATTERN,
"Illegal number format, please enter a positive/negative integer of max. " + MAX_NUMBER_LENGTH + " digits."
);
}
private static String getOperator() {
return readConsoleInput(
"Arithmetical operator (+ or -)",
OPERATOR_PATTERN,
"Unknown operator, try again."
);
}
public static int[] parseInteger(String number) {
char sign = number.charAt(0);
boolean isNegative = sign == '-' ? true : false;
if (isNegative || sign == '+')
number = number.substring(1);
int[] result = new int[ARRAY_LENGTH];
int parsePosition = number.length() - 1;
for (int i = result.length - 1; i >= 0; i--) {
if (parsePosition < 0)
break;
result[i] = number.charAt(parsePosition--) - '0';
}
return isNegative ? negate(result) : result;
}
public static int[] add(int[] operand1, int[] operand2) {
int[] result = new int[ARRAY_LENGTH];
int carry = 0;
for (int i = ARRAY_LENGTH - 1; i >= 0; i--) {
result[i] = operand1[i] + operand2[i] + carry;
if (result[i] >= 10) {
result[i] = result[i] % 10;
carry = 1;
} else
carry = 0;
}
return result;
}
public static int[] complement(int[] operand) {
int[] result = new int[ARRAY_LENGTH];
for (int i = operand.length - 1; i >= 0; i--)
result[i] = 9 - operand[i];
return result;
}
public static int[] negate(int[] operand) {
return add(complement(operand), NUMBER_ONE);
}
public static void print(int[] result, String operation) {
System.out.print(operation.charAt(0) == '-' ? "Difference = " : "Sum = ");
if (result[0] == 9) {
result = negate(result);
System.out.print("-");
}
boolean leadingZero = true;
for (int i = 0; i < result.length; i++) {
if (leadingZero) {
if (result[i] == 0)
continue;
leadingZero = false;
}
System.out.print(result[i]);
}
System.out.println(leadingZero ? "0" : "");
}
public static void main(String[] args) {
int[] operand1 = parseInteger(getOperand("#1"));
int[] operand2 = parseInteger(getOperand("#2"));
String operator = getOperator();
if (operator.equals("-"))
operand2 = negate(operand2);
int[] result = new int[ARRAY_LENGTH];
result = add(operand1, operand2);
if (DEBUG) {
System.out.println("Operand #1 = " + Arrays.toString(operand1));
System.out.println("Operand #2 = " + Arrays.toString(operand2));
System.out.println("Result = " + Arrays.toString(result));
}
print(result, operator);
}
}
Disclaimer: Your source code has multiple problems, but in order to keep it simple I am going to ignore most of them now and will just explain the reasons for your current problems and suggest fixes for them only.
If you check the array outputs from your main method, you see that the addition/subtraction results look good, i.e. the problem is not located in the calculation routines but in the print routine. There you have
duplicate code: The for loops printing the positive/negative numbers are identical.
a cosmetic problem: One leading zero is always printed.
a logical error: You check for two consecutive zeroes in order to determine where leading zeroes end and the actual number begins. But you forget that
within a number there can also be duplicate zeroes, e.g. within 10098 or -9900. This explains why 10098 is printed as 1098: You are suppressing the first zero from being printed.
if there is a zero in the last array element (e.g. 9900) you cannot check the (non-existent) subsequent element without causing an ArrayIndexOutOfBoundsException. This explains why you get the exception for -9900.
Now what can/should you do?
Eliminate the redundant for loop. You can use the same loop to print both positive and negative numbers.
Use a boolean flag in order to remember if you are still looping through leading zeroes or not.
You can change your print method like so:
public static void print(int[] result, String operation) {
System.out.print(operation.charAt(0) == '-' ? "Difference = " : "Sum = ");
if (result[0] == 9) {
result = negate(result);
System.out.print("-");
}
boolean leadingZero = true;
for (int i = 0; i < result.length; i++) {
if (leadingZero) {
if (result[i] == 0)
continue;
leadingZero = false;
}
System.out.print(result[i]);
}
System.out.println(leadingZero ? "0" : "");
}
The code after fixing the problems. all thanks to #kriegaex !
import java.util.*;
public class Program9 {
public static String getOperand() {
Scanner scan = new Scanner(System.in);
String stringOfInteger;
System.out.print("Please enter an integer up to 50 numbers: ");
stringOfInteger = scan.nextLine();
return stringOfInteger;
}
public static int[] convert(String operand) {
int [] integer = new int[50];
char ch;
int position = operand.length() - 1;
for (int i = integer.length - 1; i >= 0; i--) {
if (position >= 0)
ch = operand.charAt(position--);
else
ch = 0;
if (ch >= '0' && ch <= '9') {
integer[i] = ch - '0';
} else {
integer[i] = 0;
}
}
return integer;
}
public static int[] add(int[] operand1, int[] operand2) {
int [] result = new int[operand1.length];
int carry = 0;
for (int i = operand1.length - 1; i >= 0; i--) {
result[i] = operand1[i] + operand2[i] + carry;
if (result[i] / 10 == 1) {
result[i] = result[i] % 10;
carry = 1;
} else
carry = 0;
}
return result;
}
public static int[] complement(int[] operand2){
int [] result = new int[operand2.length];
for (int i = operand2.length - 1; i >= 0; i--)
result[i] = 9 - operand2[i];
return result;
}
public static int[] add1(int[] operand2){
int [] result = new int[operand2.length];
result[operand2.length - 1] = 1;
for (int i = result.length - 2; i >= 0; i--)
result[i] = 0;
return result;
}
public static int[] negate(int[] operand2){
return add(add1(operand2), complement(operand2));
}
public static void print(int[] result, String operation) {
if (operation.charAt(0) == '+')
System.out.print("The subtotal of the two integers = ");
else if (operation.charAt(0) == '-')
System.out.print("The subtraction of the two integers = ");
if (result[0] == 9) {
result = negate(result);
System.out.print("-");
}
boolean leadingZero = true;
for (int i = 0; i < result.length; i++) {
if (leadingZero) {
if (result[i] == 0)
continue;
leadingZero = false;
}
System.out.print(result[i]);
}
if (leadingZero == true)
System.out.println('0' - '0');
System.out.println();
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int [] result = new int[50];
String string1 = getOperand();
String string2 = getOperand();
int [] integer1 = convert(string1);
int [] integer2 = convert(string2);
String operation;
System.out.print("Please enter which operation will be used (+ or -): ");
operation = scan.nextLine();
if (operation.charAt(0) == '+')
add(integer1, integer2);
else if (operation.charAt(0) == '-')
integer2 = negate(integer2);
result = add(integer1, integer2);
System.out.println(Arrays.toString(integer1));
System.out.println(Arrays.toString(integer2));
System.out.println(Arrays.toString(add(integer1, integer2)));
print(result, operation);
}
}
I've written a code to calculate the no of factors of a given list of elements.
INPUT:
test- no of test cases
num- no of elements in 1 test case
numarr- string in which the values(whose product's factors are to be found) is divide by spaces.
When input is:
3
3
3 5 7
3
2 4 6
2
5 5
Ideally, the output should be
8
10
3
But, Exception is:
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:31)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int test = 0;
Scanner scn = new Scanner(System.in);
if (scn.hasNextLine())
test = scn.nextInt();
int op = 0;
int[] out = new int[test];
while ((test <= 100) && (test > 0)) {
int num = 0;
if (scn.hasNextLine())
num = scn.nextInt();
if (num <= 10) {
String numarr = null;
Scanner sc = new Scanner(System.in);
if (sc.hasNextLine())
numarr = sc.nextLine();
String splitt[] = null;
if (numarr != null)
splitt = numarr.split(" "); <--ERROR!!!
if (splitt.length == num) {
double[] arr = new double[splitt.length];
int i = 0;
while (i < splitt.length) {
arr[i] = Double.parseDouble(splitt[i]);
++i;
}
i = 0;
double prod = 1;
while (i < arr.length) {
prod *= arr[i];
++i;
}
double[] factor = new double[100000];
int value = 0;
pfac(prod, factor);
for (i = 0; (i < factor.length) && (factor[i] != 0); ++i) {
value += 1;
}
out[op] = value;
op++;
}
}
--test;
}
for (int i = 0; i < op; ++i) {
System.out.println(out[i]);
}
}
private static void pfac(double n, double[] factor) {
int pos = 0;
long max = (long) Math.sqrt(n);
for (long i = 1; i <= max; ++i) {
if (n % i == 0) {
factor[pos] = i;
pos += 1;
if (n / i != i) {
factor[pos] = n / i;
pos += 1;
}
}
}
}
}
Think about what your code is doing:
if(numarr!=null)
splitt=numarr.split(" ");
if(splitt.length==num)
{
...
}
If numarr is null you aren't doing the split, which means splitt is still null when you start using it.
Put the whole thing in {}.
if(numarr!=null)
{
splitt=numarr.split(" ");
if(splitt.length==num)
{
...
}
}
The line you indicate can't throw an NPE, since the preceding if statement protects that from ever happening. In the cases where numarr is null however, you will get an NPE on the next row:
if (splitt.length==num)
I would guess this is a case of you thinking the if statement is covering the next row too. It is good practice to always use curly braces in your if statements, to clearly mark where they end.
I have a string, "abc". How would a program look like (if possible, in Java) who permute the String?
For example:
abc
ABC
Abc
aBc
abC
ABc
abC
AbC
Something like this should do the trick:
void printPermutations(String text) {
char[] chars = text.toCharArray();
for (int i = 0, n = (int) Math.pow(2, chars.length); i < n; i++) {
char[] permutation = new char[chars.length];
for (int j =0; j < chars.length; j++) {
permutation[j] = (isBitSet(i, j)) ? Character.toUpperCase(chars[j]) : chars[j];
}
System.out.println(permutation);
}
}
boolean isBitSet(int n, int offset) {
return (n >> offset & 1) != 0;
}
As you probably already know, the number of possible different combinations is 2^n, where n equals the length of the input string.
Since n could theoretically be fairly large, there's a chance that 2^n will exceed the capacity of a primitive type such as an int. (The user may have to wait a few years for all of the combinations to finish printing, but that's their business.)
Instead, let's use a bit vector to hold all of the possible combinations. We'll set the number of bits equal to n and initialize them all to 1. For example, if the input string is "abcdefghij", the initial bit vector values will be {1111111111}.
For every combination, we simply have to loop through all of the characters in the input string and set each one to uppercase if its corresponding bit is a 1, else set it to lowercase. We then decrement the bit vector and repeat.
For example, the process would look like this for an input of "abc":
Bits: Corresponding Combo:
111 ABC
110 ABc
101 AbC
100 Abc
011 aBC
010 aBc
001 abC
000 abc
By using a loop rather than a recursive function call, we also avoid the possibility of a stack overflow exception occurring on large input strings.
Here is the actual implementation:
import java.util.BitSet;
public void PrintCombinations(String input) {
char[] currentCombo = input.toCharArray();
// Create a bit vector the same length as the input, and set all of the bits to 1
BitSet bv = new BitSet(input.length());
bv.set(0, currentCombo.length);
// While the bit vector still has some bits set
while(!bv.isEmpty()) {
// Loop through the array of characters and set each one to uppercase or lowercase,
// depending on whether its corresponding bit is set
for(int i = 0; i < currentCombo.length; ++i) {
if(bv.get(i)) // If the bit is set
currentCombo[i] = Character.toUpperCase(currentCombo[i]);
else
currentCombo[i] = Character.toLowerCase(currentCombo[i]);
}
// Print the current combination
System.out.println(currentCombo);
// Decrement the bit vector
DecrementBitVector(bv, currentCombo.length);
}
// Now the bit vector contains all zeroes, which corresponds to all of the letters being lowercase.
// Simply print the input as lowercase for the final combination
System.out.println(input.toLowerCase());
}
public void DecrementBitVector(BitSet bv, int numberOfBits) {
int currentBit = numberOfBits - 1;
while(currentBit >= 0) {
bv.flip(currentBit);
// If the bit became a 0 when we flipped it, then we're done.
// Otherwise we have to continue flipping bits
if(!bv.get(currentBit))
break;
currentBit--;
}
}
String str = "Abc";
str = str.toLowerCase();
int numOfCombos = 1 << str.length();
for (int i = 0; i < numOfCombos; i++) {
char[] combinations = str.toCharArray();
for (int j = 0; j < str.length(); j++) {
if (((i >> j) & 1) == 1 ) {
combinations[j] = Character.toUpperCase(str.charAt(j));
}
}
System.out.println(new String(combinations));
}
You can also use backtracking to solve this problem:
public List<String> letterCasePermutation(String S) {
List<String> result = new ArrayList<>();
backtrack(0 , S, "", result);
return result;
}
private void backtrack(int start, String s, String temp, List<String> result) {
if(start >= s.length()) {
result.add(temp);
return;
}
char c = s.charAt(start);
if(!Character.isAlphabetic(c)) {
backtrack(start + 1, s, temp + c, result);
return;
}
if(Character.isUpperCase(c)) {
backtrack(start + 1, s, temp + c, result);
c = Character.toLowerCase(c);
backtrack(start + 1, s, temp + c, result);
}
else {
backtrack(start + 1, s, temp + c, result);
c = Character.toUpperCase(c);
backtrack(start + 1, s, temp + c, result);
}
}
Please find here the code snippet for the above :
public class StringPerm {
public static void main(String[] args) {
String str = "abc";
String[] f = permute(str);
for (int x = 0; x < f.length; x++) {
System.out.println(f[x]);
}
}
public static String[] permute(String str) {
String low = str.toLowerCase();
String up = str.toUpperCase();
char[] l = low.toCharArray();
char u[] = up.toCharArray();
String[] f = new String[10];
f[0] = low;
f[1] = up;
int k = 2;
char[] temp = new char[low.length()];
for (int i = 0; i < l.length; i++)
{
temp[i] = l[i];
for (int j = 0; j < u.length; j++)
{
if (i != j) {
temp[j] = u[j];
}
}
f[k] = new String(temp);
k++;
}
for (int i = 0; i < u.length; i++)
{
temp[i] = u[i];
for (int j = 0; j < l.length; j++)
{
if (i != j) {
temp[j] = l[j];
}
}
f[k] = new String(temp);
k++;
}
return f;
}
}
You can do something like
```
import java.util.*;
public class MyClass {
public static void main(String args[]) {
String n=(args[0]);
HashSet<String>rs = new HashSet();
helper(rs,n,0,n.length()-1);
System.out.println(rs);
}
public static void helper(HashSet<String>rs,String res , int l, int n)
{
if(l>n)
return;
for(int i=l;i<=n;i++)
{
res=swap(res,i);
rs.add(res);
helper(rs,res,l+1,n);
res=swap(res,i);
}
}
public static String swap(String st,int i)
{
char c = st.charAt(i);
char ch[]=st.toCharArray();
if(Character.isUpperCase(c))
{
c=Character.toLowerCase(c);
}
else if(Character.isLowerCase(c))
{
c=Character.toUpperCase(c);
}
ch[i]=c;
return new String(ch);
}
}
```