So it's the old Exception in thread "main" java.lang.StringIndexOutOfBoundsException problem.
More precisely, (String index out of range: -1)
Obviously it's copy and paste code, otherwise I wouldn't be having problems dealing with this.
Here is the whole code, the relevant snippet is below:
import java.util.*;
import java.io.*;
public class Proj4
public static String[] cities;
public static int[][] mileage;
public static boolean[] visited;
public static int[] prev;
public static int[] dist;
public static int size;
public static void main(String[] args) throws IOException
{
Scanner fin = new Scanner(new File("cities.txt.txt"));
Scanner in = new Scanner(System.in);
size = Integer.parseInt(fin.nextLine());
cities = new String[size];
mileage = new int[size][size];
visited = new boolean[size];
prev = new int[size];
dist = new int[size];
for(int i = 0; i < size; ++i)
{
cities[i] = fin.nextLine();
}
String line = null, city1, city2;
int distance;
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < size; ++j){
mileage[i][j] = Integer.MAX_VALUE;
}
}
Here is the relevant snippet:
while(fin.hasNextLine())
{
line = fin.nextLine();
city1 = line.substring(0, line.indexOf(','));
city2 = line.substring(line.indexOf(',') + 1, line.indexOf(':'));
distance = Integer.parseInt(line.substring(line.indexOf(':') + 1));
mileage[index(city1)][index(city2)] = distance;
mileage[index(city2)][index(city1)] = distance;
}
while(true)
{
System.out.print("Enter the first city: ");
city1 = in.nextLine();
System.out.print("Enter the second city: ");
city2 = in.nextLine();
int startInd = index(city1);
int stopInd = index(city2);
if(startInd == -1 || stopInd == -1){
System.out.println("Invalid city name(s)");
}
else
{
dijkstra(city1);
print(city1, city2);
}
System.out.print("Another pair? (Y/N): ");
line = in.nextLine();
if(line.equalsIgnoreCase("N"))
{
break;
}
}
}
public static int index(String name)
{
for(int i = 0; i < cities.length; ++i)
{
if(cities[i].equalsIgnoreCase(name))
{
return i;
}
}
return -1;
}
public static void init(String start) {
int startInd = index(start);
for(int i = 0; i < size; ++i){
dist[i] = Integer.MAX_VALUE;
prev[i] = -1;
visited[i] = false;
}
dist[startInd] = 0;
}
public static int minIndex()
{
int minInd = -1, minDistance = Integer.MAX_VALUE;
for(int i = 0; i < size; ++i)
{
if(!visited[i] && dist[i] < minDistance)
{
minInd = i;
minDistance = dist[i];
}
}
return minInd;
}
public static boolean done()
{
for(int i = 0; i < size; ++i)
{
if(!visited[i])
{
return false;
}
}
return true;
}
public static void print(String start, String stop)
{
int startInd = index(start);
int stopInd = index(stop);
List<String> intCities = new ArrayList<>();
int prevInd = prev[stopInd];
while(prevInd != startInd)
{
intCities.add(cities[prevInd]);
prevInd = prev[prevInd];
}
System.out.print(start + "->");
for(int i = intCities.size() - 1; i >= 0; --i)
{
System.out.print(intCities.get(i) + "->");
}
System.out.println(stop + ", distance " + dist[stopInd] + " miles");
}
public static void dijkstra(String start)
{
init(start);
while(!done())
{
int x = minIndex();
visited[x] = true;
for(int y = 0; y < size; ++y)
{
if(!visited[y])
{
if(mileage[x][y] != Integer.MAX_VALUE)
{
int dy = dist[x] + mileage[x][y];
if(dy < dist[y])
{
dist[y] = dy;
prev[y] = x;
}
}
}
}
}
}
}
Apologies for the poor formatting, this is my first time asking here. Thanks!
It is possible that your input string doesnt have ','(comma) or ':'(colon), so that indexOf() method will return -1 in your relevant snippet code section which results in java.lang.StringIndexOutOfBoundsException String index out of range: -1 .
Check your input by enabling debugger on line line = fin.nextLine();
OR add print statement in after taking input System.out.println(line)
I'm trying to code a cipher project where the objective is for a user to send in a text and shift number. The result would be printed accordingly. For instance, if I sent "Hello World" with a shift value of 1, it should print: "Gfmmp Xrsme". The problem is that I'm having trouble with the shifting because I have an arraylist of char values (the alphabet).
This is what I have so far:
import java.util.ArrayList;
public class CaesarCipher
{
int shift;
String inputText;
ArrayList<String> arr;
ArrayList<String> exchange = new ArrayList<String>();
public CaesarCipher()
{
shift = 0;
inputText = "";
}
public CaesarCipher(int s, String iT)
{
shift = s;
inputText = iT;
}
public void alphabet()
{
arr = new ArrayList<String>();
arr.add("A");
arr.add("B");
arr.add("C");
arr.add("D");
arr.add("E");
arr.add("F");
arr.add("G");
arr.add("H");
arr.add("I");
arr.add("J");
arr.add("K");
arr.add("L");
arr.add("M");
arr.add("N");
arr.add("O");
arr.add("P");
arr.add("Q");
arr.add("R");
arr.add("S");
arr.add("T");
arr.add("U");
arr.add("V");
arr.add("W");
arr.add("X");
arr.add("Y");
arr.add("Z");
}
public void convert()
{
String revisedText = inputText.replaceAll("\\s","");
//Turn revisedText into an array and match it with array above
revisedText.toUpperCase();
int j = 1;
String letter = "";
for (int i = 0; i < revisedText.length(); i++)
{
exchange.add(revisedText.substring(i, j));
j++;
}
}
public void shift()
{
shift = shift % 26 + 26;
ArrayList<String> newArr = new ArrayList<String>(); // array with shifted values
int pos = 0;
for(int r = 0; r < exchange.size(); r++)
{
if(arr.get(r).equals(exchange.get(r)))
arr.indexOf(r) + shift = pos;
}
}
public String toString()
{
return "";
}
}
Here is quick for loop for an example
String string = "Hello World";
String newPhrase = "";
int shift = 1;
for(int i = 0; i < string.length(); i++){
if(string.charAt(i) != ' ')
newPhrase += (char)(string.charAt(i) + shift);
else
newPhrase += ' ';
}
System.out.println(string + " -> " + newPhrase);
Output
Hello World -> Ifmmp Xpsme
However you should note that there are a couple edge cases i am not checking for. Once you understand the above code you should be able to find the edge cases I am talking about.
I feel as though I have the math and logic correct, I'm not sure what I'm doing wrong. Iv'e tried it with a few different values of b and nothing works. For some reason, "f" is always changed to "v" and "k" always to "q", no matter the constant used. My output is: glqvafkpuzejotydinsxchmrwb, abcdwvghijqlmnolqrstgvwxyb. Decipher method works when b = 0.
public class Asgn2No2CodeDecode {
public static void main(String[] args) {
System.out.println(affineCipher("abcdefghijklmnopqrstuvwxyz"));
System.out.println(affineDecipher(affineCipher("abcdefghijklmnopqrstuvwxyz")));
}
public static String affineCipher(String plainTxt)
{
StringBuilder cipherTxt = new StringBuilder();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
int a = 5;
int b = 6;
int charNum = 0;
char alphChar;
char ciphChar;
for (int i = 0; i < plainTxt.length(); i++)
{
ciphChar = plainTxt.charAt(i);
if (Character.isLetter(ciphChar))
{
for (int j = 0; j<alphabet.length(); j++)
{
alphChar = alphabet.charAt(j);
if (ciphChar == alphChar)
{
charNum = ((a*j + b)%26);
}//end if
}//end for alph
cipherTxt.append(alphabet.charAt(charNum));
}else cipherTxt.append(plainTxt.charAt(i));
}//end for plain
return cipherTxt.toString();
}//end affineCipher(String)
public static String affineDecipher(String cipherTxt)
{
StringBuilder plainTxt = new StringBuilder();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
int aInv = 21;
int b = 6;
int charNum = 0;
char alphChar;
char ciphChar;
for (int i = 0; i < cipherTxt.length(); i++)
{
ciphChar = cipherTxt.charAt(i);
if (Character.isLetter(ciphChar))
{
for (int x = 0; x<alphabet.length(); x++)
{
alphChar = alphabet.charAt(x);
if (ciphChar == alphChar)
{
if (x>=b)
{
charNum = (((aInv*(x-b))%26));
}
else charNum = (-((aInv*(x-b))%26));
}//end if
}//end for alph
plainTxt.append(alphabet.charAt(charNum));
}else plainTxt.append(cipherTxt.charAt(i));
}//end for plain
return plainTxt.toString();
}//end affineCipher(String)
}
I am looking for some help with a project i am working on. I am relatively new to java and am working to make a function to generate a password. There is probably alot of error in this or this might be completely wrong so please be nice to a newbie >.<
import java.util.Random;
public class StillTesting {
public static void main(String[] args) {
System.out.println("Your new password is: " + generateValidPassword());
}
static private String generateValidPassword() {
String numcase = "";
String lowcase = "";
String upcase = "";
String halfpass = numcase.concat(upcase);
String returnString = halfpass.concat(lowcase);
System.out.print(returnString);
Random r = new Random();
String loweralphabet = "abcdefghijklmnopqrstuvwxyz";
int n = loweralphabet.length();
String upperalphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int N = upperalphabet.length();
int num = 0;
for (int i = 0; i < 3; i++) {
num = r.nextInt(9);
numcase = String.valueOf(num = r.nextInt(9));
return numcase;
}
for (int i = 0; i < 3; i++) {
lowcase = String.valueOf(loweralphabet.charAt(r.nextInt(n)));
return lowcase;
}
for (int i = 0; i < 3; i++) {
upcase = String.valueOf(upperalphabet.charAt(r.nextInt(N)));
return upcase;
}
return returnString;
}
}
You may want to try removing your return statements in your loop something like this:
static private String generateValidPassword()
{
String numcase = "";
String lowcase = "";
String upcase = "";
String halfpass = "";
String returnString = "";
System.out.print(returnString);
Random r = new Random();
String loweralphabet = "abcdefghijklmnopqrstuvwxyz";
int n = loweralphabet.length();
String upperalphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int N = upperalphabet.length();
int num = 0;
for(int i=0;i<3;i++)
{
num=r.nextInt(9);
numcase = String.valueOf(num);
returnString += numcase;
}
for(int i=0;i<3;i++)
{
lowcase = String.valueOf(loweralphabet.charAt(r.nextInt(n)));
returnString += lowcase;
}
for(int i=0;i<3;i++)
{
upcase = String.valueOf(upperalphabet.charAt(r.nextInt(N)));
returnString += upcase;
}
return returnString;
}
This will give you output like 637xiqHMR. You will combine the letters generated from each loop into one string then return the whole string at the end instead of returning at first iteration of first loop.
Is this what you are looking for? The output of the following program is something like 433raeWPV and 675croJWV
public static void main(String[] args) {
System.out.println("Your new password is: " + generateValidPassword());
}
static private String generateValidPassword() {
String pswd = "";
Random r = new Random();
String loweralphabet = "abcdefghijklmnopqrstuvwxyz";
int n = loweralphabet.length();
String upperalphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int N = upperalphabet.length();
int num = 0;
for (int i = 0; i < 3; i++) {
num = r.nextInt(9);
pswd += String.valueOf(num = r.nextInt(9));
}
for (int i = 0; i < 3; i++) {
pswd += String.valueOf(loweralphabet.charAt(r.nextInt(n)));
}
for (int i = 0; i < 3; i++) {
pswd += String.valueOf(upperalphabet.charAt(r.nextInt(N)));
}
return pswd;
}
Alright, indeed there are some mistakes:
You are setting halfpass and returnString values before assigning the values of numcase, upcase and lowcase
You are returning a value in the first iteration of every for loop, The first return statement will return the first numcase value. More info about how the return statement works here
at the end, the returnString statement is never reached.
Try something like this:
static private String generateValidPassword()
{
String numcase = "";
String lowcase = "";
String upcase = "";
Random r = new Random();
String loweralphabet = "abcdefghijklmnopqrstuvwxyz";
int n = loweralphabet.length();
String upperalphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int N = upperalphabet.length();
int num = 0;
for(int i=0;i<3;i++)
{
num=r.nextInt(9);
numcase += String.valueOf( num = r.nextInt(9));
}
for(int i=0;i<3;i++)
{
lowcase += String.valueOf(loweralphabet.charAt(r.nextInt(n)));
}
for(int i=0;i<3;i++)
{
upcase += String.valueOf(upperalphabet.charAt(r.nextInt(N)));
}
String halfpass = numcase.concat(upcase);
String returnString = halfpass.concat(lowcase);
System.out.print(returnString);
return returnString;
}
}
Well, it looks like a few people spotted the bugs while I was working, but as I've tidied up the whole thing you might like to take a look at this working version which addresses most of the issues in the original:
import java.util.Random;
public class StillTesting {
public static void main( String[] args )
{
System.out.println("Your new password is: " + generateValidPassword());
}
static private String generateValidPassword()
{
StringBuilder password = new StringBuilder();
Random r = new Random();
final String loweralphabet = "abcdefghijklmnopqrstuvwxyz";
final String upperalphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(int i=0;i<3;i++)
{
password.append(String.valueOf(r.nextInt(10)));
}
for(int i=0;i<3;i++)
{
password.append(loweralphabet.charAt(r.nextInt(loweralphabet.length())));
}
for(int i=0;i<3;i++)
{
password.append(upperalphabet.charAt(r.nextInt(upperalphabet.length())));
}
return password.toString();
}
}
I have array
data[][];
convert to string:
string = Arrays.deepToString(data);
string:
[[1, 1394119227787, 59474093, USD/DKK, true, 0.05, 5.391582, 5.00663, 5.39663, null, null], [1, 1394581174413, 59500543, EUR/JPY, false, 0.05, 142.489381, 145.3, 139.68, null, null],
[1, 1394581174413, 59500543, EUR/JPY, false, 0.05, 142.489381, 145.3, 139.68, null, null],
[1, 1394581174413, 59500543, EUR/JPY, false, 0.05, 142.489381, 145.3, 139.68, null, null]]
and How convert this string back to array?
Try my stringToDeep() method to convert back to Array.
import java.util.*;
public class DeepToArray {
public static void main(String[] args) {
int row, col;
row = 2;
col = 3;
String[][] in = new String[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
in[i][j] = i + " " + j;
}
}
String str = Arrays.deepToString(in);
System.out.println(str);
String[][] out = stringToDeep(str);
for (String s2[] : out) {
for (String s3 : s2) {
System.out.print(s3 + " ");
}
System.out.println();
}
}
private static String[][] stringToDeep(String str) {
int row = 0;
int col = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '[') {
row++;
}
}
row--;
for (int i = 0;; i++) {
if (str.charAt(i) == ',') {
col++;
}
if (str.charAt(i) == ']') {
break;
}
}
col++;
String[][] out = new String[row][col];
str = str.replaceAll("\\[", "").replaceAll("\\]", "");
String[] s1 = str.split(", ");
int j = -1;
for (int i = 0; i < s1.length; i++) {
if (i % col == 0) {
j++;
}
out[j][i % col] = s1[i];
//System.out.println(s1[i] + "\t" + j + "\t" + i % col);
}
return out;
}
}
There is no method in the java API that will automatically convert this back to an array. You could write code to do this yourself, but it would be tricky; this format does not escape special characters like the square brackets, or the commas. It might be easier just to use a format which is designed for encoding and decoding arrays, like JSON.
All the answers I found are 2-dimensional only, so here's my solution to reverse deepToString(...) for any number of dimensions:
Usage example:
String arrString = "[[[0.11695497071135137, 0.8830064157596283, 0.3433854446148375, 0.18825445694298526, 1.0441938749175883, 0.8941633746325311], [-0.089908138214512, 0.39821330927870574, 0.1365997500579524, 0.7008902956765364, 0.9897596683277262, 0.2847717055995359], [0.6450670283688857, 0.01516064860567864, -0.07904927386204857, 0.2703900981351612, 0.45402985012492075, 0.30505608337251183], [0.5122943117220898, 0.008726346575469023, 0.7734611917871235, 0.3051772999891666, 0.5237487372571624, 1.1824105144656751]]]";
String[][][] arr = (String[][][]) reverseDeepToString(arrString);
System.out.println(Arrays.deepToString(arr));
This code converts a string (arrString) into an array, and then the function Arrays.deepToString(...) converts it back into the same string.
Function code:
public static Object reverseDeepToString(String str){
int dimensions = 0;
for(int x = 0; x < str.length(); x++)
if(str.charAt(x) == '[')
dimensions++;
else break;
str = str.substring(dimensions, str.length() - dimensions);
return createArrayRecursive(str, dimensions);
}
private static Object createArrayRecursive(String str, int dimension){
if(dimension == 1)
return str.split(", "); // modify the code here if you want to convert the strings to another variable type
String[] s = str.split(getArraySeparator(dimension));
int[] lengths = new int[dimension];
lengths[0] = s.length;
Object arr = Array.newInstance(String.class, lengths); // and here (see comment above)
for(int x = 0; x < s.length; x++)
Array.set(arr, x, createArrayRecursive(s[x], dimension - 1));
return arr;
}
private static String getArraySeparator(int dimension){
String separator = ", ";
for(int x = 1; x < dimension; x++)
separator = ']' + separator + "\\[";
return separator;
}
Array to string and back to array :P
import java.util.Arrays;
import java.util.Random;
public class arrays {
public static void main(String [ ] args)
{
String[][] in = new String [10][4];
String[][] out = new String [10][4];
arrays nr = new arrays();
for(int i =0; i< 4; i++){
for(int j =0; j< 4; j++){
in[i][j] = nr.Rand(5);
}
}
System.out.println(Arrays.deepToString(in));
// tablica ok
// convert array to string
String line = "";
for(int i =0; i< 4; i++){
for(int j =0; j< 4; j++){
line += in[i][j] + "_";
}
line += ":";
}
System.out.println(line);
// line back to array
String[] xline = line.split(":");
int ss = 0;
for (String str : xline) {
out[ss] = (String[]) str.split("_");
System.out.println("string line>>>" + str);
ss++;
}
System.out.println(Arrays.deepToString(out));
}
public String nextSessionId() {
//private SecureRandom random = new SecureRandom();
//return new BigInteger(130, random).toString(32);
return null;
}
public String Rand(int zz){
char[] chars = "987654321abcdefghijklm111nopqrstuvwxyz0123456789".toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < zz; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
// System.out.println(output);
return output;
}
}
:D