How to organize strings through a sort method - java

This is a program that lets user input 6 random letters, and the program sorts these letters in order. Ex user inputs j, d, e, l, w, q and program outputs d, e, j, l, q, w.
Unfortunately the code freaks out and does not sort a thing. Note: I am using a GUI
Under public I created a class and an array to eventually house all inputted letters
class Abc {
String letter;
Abc (String _letter) {
letter = _letter;
}
}
ArrayList <Abc> alphabet = new ArrayList <Abc>(3); //note its 3, not 6 like in the example
After user types in a letter in a textField, they press the "addButton" which adds and saves the value in the array.
String letter = letterField.getText();
//Store values in array
Abc a = new Abc(letter);
alphabet.add(a);
Now for the actual 'sorting' part. Which takes place after user presses a "Play" button.
String[] abc = new String[3]; //LINE I FORGOT TO ADD
for (int k = 0; k < abc.length; k++) {
abc[k] = letterField.getText();
int x;
for (int i = 0; i < abc.length; i++) {
// Asume first value is x
x = i;
for (int j = i + 1; j < abc.length; j++) {
//find smallest value in array (random)
if (abc[j].compareToIgnoreCase(abc[x]) < 0) {
x = j;
}
}
if (x != i) {
//swap the values if not in correct order
final String temp = abc[i];
abc[i] = abc[x];
abc[x] = temp;
}
textArea.append(abc[i] + "\n");// Output correct order
}
}
I had originally used this code to sort integers, the only difference between that program and this program is the int/String and this one I am currently working on allows the user to input the letters and the program does not randomize them like it did with the integer program.
I had thought this would be enough code to do the trick and organize some letters, but apparently not.
For the actually problem, when I input the letters and add them to the array and press "play" the program freaks and a lovely error pops up...
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "d"
Note: 'd' being the last letter I inputted for the last time I tested the program...all of five seconds ago.
Any hints or advice would be greatly appreciated!

A NumberFormatException is thrown when you attempt to parse some text into a number, but the text is not a number, such as in your example: "d".
You mentioned that you had this code working with integers, then converted it to work with letters. Most likely, you forgot to take out the code (which you haven't shown here) that parses the input into a number. You should take out that code and accept the user's input as text as originally inputted.

You are probably using parseInt() or something similar in the part of the code, where you get input from user. That method should be off now, as you no longer want to change input from String to any number.
By the way, just for information, class Arrays in java include some sorting methods. You can check those at this site

Related

Java - getting and using the integers from an array (0-how ever many the user inputted)

My program requires an input of as many integers as the user wishes on a SINGLE line. My program must then, take the first integer the user entered decide if it is in the range or not. If NOT output error, If YES then do specified conversion. THEN move to the SECOND integer entered by the user (if there is one).
The way I have tackled this so far is this...
System.out.print("Enter a digit(s). ");
//Gets input numbers and stores them as a whole string
//e.g if enters 1 2 3 input will = "1 2 3"
String input = kbd.nextLine();
//Splits the input at every space and stores them in an array
//e.g If input = "1 2 3", numbers {"1", "2", "3"}
String[] numbersString = input.split(" ");
//Creates an array the same length as our String array
//How we will store each number as an integer instead of a string
int[] numbers = new int[numbersString.length];
//a loop that goes through the array as a string
for ( int i = 0; i < numbersString.length; i++ )
{
// Turns every value in the numbersString array into an integer
// and puts it into the numbers array.
numbers[i] = Integer.parseInt(numbersString[i]);
}
My problem is that I don't know how to GET the first integer entered and then on to the second and so on... (I DONT UNDERSTAND HOW to access the array of integers ive obtained from the user and manipulate them from 1 - how ever many entered.
You access the array in a similar way to how you built it. For example, to print out the array, you can do this:
for ( int i = 0; i < numbers.length; i++ )
{
System.out.println(numbers[i]);
}
Note how the for loop is nearly identical to the last for loop in the code you posted. The only difference is numbers.length since you want to iterate over the numbers array.
You should also take the time to learn about the enhanced for loop which makes iterating over an array much easier.
What about something like this:
for(int number : numbers) //iterates through each number in the array of numbers
{
if(number > 4 && number < 10) //or whatever range you wanted
{
number *= 2; //or whatever conversion you wanted
System.out.println(number);
}
}
This uses an enhanced for loop as mentioned in comment above. The variable number (singular) is each int in your array of numbers.

Why isn't this code reversing user inputted text?

System.out.println("type something to get it back reversed...");
Scanner sc1 = new Scanner(System.in);
String x = sc1.nextLine();//user input
for(int i = x.length(); i > 0; i--)
{
System.out.print(x.substring(i));
}
In this code, I want to take user-inputted text and output it in reverse order (i.e. dog = god) with a for-loop and the substring method. The above code is non-functional.
For example...
-when I input "dog", I get "gog".
-when I input "computer", I get "rerteruterputermputeromputer"
It never outputs the first letter of the text. I'd be very grateful if somebody could help me out and explain this to me :)
See the API for the String class. The String.substring(int index) method creates a substring from the parameter index to the end of the String (so if x is dog, the x.substring(0) results in 'dog'. Perhaps you wish to use the two parameter substring method. Also note the indexes of the loop, starting at length - 1 and ending at 0
for ( int i = x.length()-1; i >= 0; i-- ){
System.out.print(x.substring(i, i+1));
}
substring(i) returns everything in your string from i to the end. To get the character at position i in a string, use charAt(i).
Also, the last index of the string is x.length()-1. The first is zero. So your loop should be something like:
for (int i = x.length()-1; i>=0; --i) {
System.out.print(x.charAt(i));
}
As copeg explained, substring() returns all characters after the character i. An easier solution would be to use charAt():
for(int i = x.length()-1; i >= 0; i--) {
System.out.print(x.charAt(i));
}

Find every possible subset given a string [duplicate]

This question already has answers here:
Memory efficient power set algorithm
(5 answers)
Closed 8 years ago.
I'm trying to find every possible anagram of a string in Java - By this I mean that if I have a 4 character long word I want all the possible 3 character long words derived from it, all the 2 character long and all the 1 character long. The most straightforward way I tought of is to use two nested for loops and iterare over the string. This is my code as of now:
private ArrayList<String> subsets(String word){
ArrayList<String> s = new ArrayList<String>();
int length = word.length();
for (int c=0; c<length; c++){
for (int i=0; i<length-c; i++){
String sub = word.substring(c, c+i+1);
System.out.println(sub);
//if (!s.contains(sub) && sub!=null)
s.add(sub);
}
}
//java.util.Collections.sort(s, new MyComparator());
//System.out.println(s.toString());
return s;
}
My problem is that it works for 3 letter words, fun yelds this result (Don't mind the ordering, the word is processed so that I have a string with the letters in alphabetical order):
f
fn
fnu
n
nu
u
But when I try 4 letter words, it leaves something out, as in catq gives me:
a
ac
acq
acqt
c
cq
cqt
q
qt
t
i.e., I don't see the 3 character long word act - which is the one I'm looking for when testing this method. I can't understand what the problem is, and it's most likely a logical error I'm making when creating the substrings. If anyone can help me out, please don't give me the code for it but rather the reasoning behind your solution. This is a piece of coursework and I need to come up with the code on my own.
EDIT: to clear something out, for me acq, qca, caq, aqc, cqa, qac, etc. are the same thing - To make it even clearer, what happens is that the string gets sorted in alphabetical order, so all those permutations should come up as one unique result, acq. So, I don't need all the permutations of a string, but rather, given a 4 character long string, all the 3 character long ones that I can derive from it - that means taking out one character at a time and returning that string as a result, doing that for every character in the original string.
I hope I have made my problem a bit clearer
It's working fine, you just misspelled "caqt" as "acqt" in your tests/input.
(The issue is probably that you're sorting your input. If you want substrings, you have to leave the input unsorted.)
After your edits: see Generating all permutations of a given string Then just sort the individual letters, and put them in a set.
Ok, as you've already devised your own solution, I'll give you my take on it. Firstly, consider how big your result list is going to be. You're essentially taking each letter in turn, and either including it or not. 2 possibilities for each letter, gives you 2^n total results, where n is the number of letters. This of course includes the case where you don't use any letter, and end up with an empty string.
Next, if you enumerate every possibility with a 0 for 'include this letter' and a 1 for don't include it, taking your 'fnu' example you end up with:
000 - ''
001 - 'u'
010 - 'n'
011 - 'nu'
100 - 'f'
101 - 'fu' (no offense intended)
110 - 'fn'
111 - 'fnu'.
Clearly, these are just binary numbers, and you can derive a function that given any number from 0-7 and the three letter input, will calculate the corresponding subset.
It's fairly easy to do in java.. don't have a java compiler to hand, but this should be approximately correct:
public string getSubSet(string input, int index) {
// Should check that index >=0 and < 2^input.length here.
// Should also check that input.length <= 31.
string returnValue = "";
for (int i = 0; i < input.length; i++) {
if (i & (1 << i) != 0) // 1 << i is the equivalent of 2^i
returnValue += input[i];
}
return returnValue;
}
Then, if you need to you can just do a loop that calls this function, like this:
for (i = 1; i < (1 << input.length); i++)
getSubSet(input, i); // this doesn't do anything, but you can add it to a list, or output it as desired.
Note I started from 1 instead of 0- this is because the result at index 0 will be the empty string. Incidentally, this actually does the least significant bit first, so your output list would be 'f', 'n', 'fn', 'u', 'fu', 'nu', 'fnu', but the order didn't seem important.
This is the method I came up with, seems like it's working
private void subsets(String word, ArrayList<String> subset){
if(word.length() == 1){
subset.add(word);
return;
}
else {
String firstChar = word.substring(0,1);
word = word.substring(1);
subsets(word, subset);
int size = subset.size();
for (int i = 0; i < size; i++){
String temp = firstChar + subset.get(i);
subset.add(temp);
}
subset.add(firstChar);
return;
}
}
What I do is check if the word is bigger than one character, otherwise I'll add the character alone to the ArrayList and start the recursive process. If it is bigger, I save the first character and make a recursive call with the rest of the String. What happens is that the whole string gets sliced in characters saved in the recursive stack, until I hit the point where my word has become of length 1, only one character remaining.
When that happens, as I said at the start, the character gets added to the List, now the recursion starts and it looks at the size of the array, in the first iteration is 1, and then with a for loop adds the character saved in the stack for the previous call concatenated with every element in the ArrayList. Then it adds the character on its own and unwinds the recursion again.
I.E., with the word funthis happens:
f saved
List empty
recursive call(un)
-
u saved
List empty
recursive call(n)
-
n.length == 1
List = [n]
return
-
list.size=1
temp = u + list[0]
List = [n, un]
add the character saved in the stack on its own
List = [n, un, u]
return
-
list.size=3
temp = f + list[0]
List = [n, un, u, fn]
temp = f + list[1]
List = [n, un, u, fn, fun]
temp = f + list[2]
List = [n, un, u, fn, fun, fu]
add the character saved in the stack on its own
List = [n, un, u, fn, fun, fu, f]
return
I have been as clear as possible, I hope this clarifies what was my initial problem and how to solve it.
This is working code:
public static void main(String[] args) {
String input = "abcde";
Set<String> returnList = permutations(input);
System.out.println(returnList);
}
private static Set<String> permutations(String input) {
if (input.length() == 1) {
Set<String> a = new TreeSet<>();
a.add(input);
return a;
}
Set<String> returnSet = new TreeSet<>();
for (int i = 0; i < input.length(); i++) {
String prefix = input.substring(i, i + 1);
Set<String> permutations = permutations(input.substring(i + 1));
returnSet.add(prefix);
returnSet.addAll(permutations);
Iterator<String> it = permutations.iterator();
while (it.hasNext()) {
returnSet.add(prefix + it.next());
}
}
return returnSet;
}

String replace isn't working in for loop - Java

For some reason this code doesn't work.
public void actionPerformed(ActionEvent e) {
Random random = new Random();
int randomChar = random.nextInt((23 - 0) + 1);
for(int x = 23;x > 0;x-- ) {
String text;
text = original.getText();
text = text.toLowerCase();
text = text.replace(alphabet[x], alphabet[randomChar]);
newText.setText(text);
}
Just to clear a couple things up original and newText are JTextField, and alphabet is a char array with a-z.
Now when I run this it should go through and replace every character with a random one, starting at Z and ending at A however it just gives me the exact same string that I entered back, just converted to lowercase.
It's worth noting that if I replace
text = text.replace(alphabet[x], alphabet[randomChar]);
With
text = text.replace(alphabet[0], alphabet[randomChar]);
And put a bunch of A's into the input box it does change them into a random letter. EG:
aaaa input
llll output
or gggg output
it just doesn't work if I have a variable in there.
The rest of the code isn't important by the way, it's all declaring variables and setting up the GUI.
Any help is much appreciated!
In addition to moving the random character generation inside the loop (as suggested by #CIsForCoocckies), you'll also need to move the getText() and setText() calls outside the loop (because each time the loop is run, you start over with the original text so at most one kind of character would be replaced in the end, no matter how many times the loop iterates.
your randomchar is set before the loop with some char and then all chars are replaced to said char so - "yourstring" becomes "xxxxxxxxxx" where x=randomchar
In addition to the two other answers, I'd like to add a comment to the for loop:
for(int x = 23;x > 0;x--)
You won't enter the loop when x == 0 at all, which means the first char in your alphabet array won't be considered for replacement.
If you have the alphabet array already and want to replace every character with a random one, why not consider using:
for (int x = 0; x < alphabet.length; x++){
//your code here
}
This should be better than hard-coding

Out of bounds. Trying to access index 98 for no apparent reason

As a challenge to my beginner programming ability I thought it would be fun to see if I could code a simple brute force password thing. So I've started writing an application which generates, given a value for the length of the string, every alphanumeric permutation it could take. However, as I am a complete programming newbie I am having troubles.
Firstly, despite having imported java.lang.Math, I'm getting errors saying cannot find symbol: pow. I managed to fix this by writing out in full java.lang.Math.pow(); when I use the function instead, but why that works but import does not is beyond me.
Secondly, regardless of the length input, after inputting I get the runtime error:
aaException in thread "main" java.lang.ArrayIndexOutOfBoundsException: 98
at combination.main(combination.java:53)
Which suggests that in line 53:
current[j] = alphanum[((int)current[j])+1];
I'm apparently trying to access index 98 in either current[] or alphanum[]?
Which as far as I can see shouldn't be happening...
I'm fairly stumped by this development. Anyway, here's my code:
//48-57 65-90 97-122
import java.util.Scanner;
import java.lang.Math;
public class combination {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//Alphanum will be an array of chars: the lowercase letters of the alphabet, the uppercase, and the numbers 0-9.
char[] alphanum = new char[62];
//Set indexes 0-25 as lowercase a-z, and indexes 26-51 as uppercase A-Z, using ascii conversion.
for (int i=0; i<26; i++) {
alphanum[i] = (char)(i+97);
alphanum[i+26] = (char)(i+65);
}
//Set indexes 51-61 as 0-9.
for (int i=0; i<10; i++) {
alphanum[i+52] = (char)(i+48);
}
//Take in variable for length.
System.out.print("Enter length: ");
int length = in.nextInt();
//Current will be an array of chars: it will hold the current permutation being generated.
char[] current = new char[length];
//Set all indexes in current to "a" by default, and print this string as the first permutation.
for (int i=0; i<length; i++) {
current[i] = alphanum[0];
System.out.print(current[i]);
}
//power will be a temporary double, used to calculate the number of iterations needed, as the pow function works with doubles.
double power = (java.lang.Math.pow(62.00, ((double)length)));
//Convert power to an integer, iterations, and subtract 1 because one iteration was already printed previously.
int iterations = ((int)power)-1;
/*The loop works like this. The rightmost char is checked, and if it is the maximum value of the idex
it is reverted to idex 0 again and the index value of the char to the left of it is increased by 1,
if it is not the maximum then it is just increased by 1. This is iterated the right number of times such
that every alphanumeric permutation of that length has been returned.*/
for (int i=0; i<iterations; i++) {
for (int j=(length-1); j>=0; j--) {
if ((j!=0) && (((int)current[j])==122)) {
current[j] = alphanum[0];
current[j-1] = alphanum[((int)current[j-1])+1];
} else if (j!=0) {
current[j] = alphanum[((int)current[j])+1];
} else {
System.out.println("This has looped too many times. Something is wrong.");
}
}
//At the end of each iteration, print the string.
for (int l=0; l<length; l++) {
System.out.print(current[l]);
}
}
}
}
I'd be really thankful for any help or insight you could offer. ^_^
Your alphanum array has size 62, and the meaning of ((int)current[j-1])+1 is 98 (> 62).
The int value of char 'a' is 97.
I'm apparently trying to access index 98 in either current[] or
alphanum[]? Which as far as I can see shouldn't be happening...
This is perfectly possible since you try to access an element in alphanum at a certain index, where the index is derived from the contents of your current array. I suggest you print out the contents of those arrays at different steps and you will quickly discover where exactly your code behaves not as you thought it would
current[j] = alphanum[((int)current[j])+1];
Here you try to access
int index = ((int)current[j])+1;
current[j] = alphanum[index];
where index seems to be 98

Categories