Alphabetize individual strings from list - Java - java

I want to read in a list of words. Then I want alphabetize each of the characters within each word such that I have an entire list of words where each letter is alphabetized. For example if I wanted to read in "cat" "dog" "mouse" from a text file I would have [a,c,t], [d,g,o], and [e,m,o,s,u].
I'm implementing this in Java. I thought about a linked list or some other Collection but I'm not really sure how to implement those with respect to this. I know it's not as simple as converting each string to a char array or using array list. (I already tried those)
Does anyone have any suggestions or examples of doing this?
Basically, I'm just trying to get better with algorithms.
public class AnagramSolver1 {
static List<String> inputList = new ArrayList<String>();
public static void main(String[] args) throws IOException {
List<String> dictionary = new ArrayList<String>();
BufferedReader in = new BufferedReader(new FileReader("src/dictionary.txt"));
String line = null;
Scanner scan = new Scanner(System.in);
while (null!=(line=in.readLine()))
{
dictionary.add(line);
}
in.close();
char[] word;
for (int i = 0; i < dictionary.size(); i++) {
word = inputList.get(i).toCharArray();
System.out.println(word);
}

If you have a String called word, you can obtain a sorted char[] of the characters in word via Arrays.sort
char[] chars = word.toCharArray();
Arrays.sort(chars);
I assume you would want to repeat this process for each member of a collection of words.
If you're interested in knowing what happens behind the scenes here, I would urge you to take a look at the source.

Java provides good support for sorting already: all you need is converting your String to an array of char[], call Arrays.sort on it, and then convert that array back to String.
If you want to have some fun with algorithms, however, you could try going for a linear counting sort: count the letters in the original, then go through the counts in alphabetical order, and write out the count number of characters.

Related

Is there a way to concatenate Java strings in less than O(n) time?

My homework question involves joining strings in a particular sequence. We are first given the strings, followed by a set of instructions that tell us how to concatenate them; finally we print the output string.
I have used the Kattis FastIO class to handle buffered input and output. Below is my algorithm, which iterates through the instructions to concatenate the strings. I have tried making the array of normal strings, StringBuffers and StringBuilders.
The program seems to work as intended, but it gives a time limit error on my submission platform due to inefficiency. It seems like appending the way I did is O(n); is there any faster way?
public class JoinStrings {
public static void main(String[] args) {
Kattio io = new Kattio(System.in, System.out);
ArrayList<StringBuilder> stringList = new ArrayList<StringBuilder>();
int numStrings = io.getInt();
StringBuilder[] stringArray = new StringBuilder[numStrings];
for (int i = 0; i < numStrings; i++) {
String str = io.getWord();
stringArray[i] = new StringBuilder(str);
}
StringBuilder toPrint = stringArray[0];
while (io.hasMoreTokens()) {
int a = io.getInt();
int b = io.getInt();
stringArray[a-1].append(stringArray[b-1]); // this is the line that is done N times
toPrint = stringArray[a-1];
}
io.println(toPrint.toString());
io.flush();
}
}
The StringBuilder.append() copy char from new string to existing string. It's fast but not free.
Instead of keeping appending the String to the StringBuilder array, keep track of the String indexes need to appended. Then finally append the Strings stored in the print out indexes list.

HashSet Java find words according to length

Write a method that takes two parameters (1) the original string and (2) the word length and
returns a new string that contains the words of the specified length from the original string without
any duplicates. Here is an example of program execution:
getWordsOfLengthN(“We are the best, are we ?”, 3)  “are the”
getWordsOfLengthN(“We are the best, are we ?”, 2)  “we”
Notice that the method considers does not differentiate between the upper and lower cases.
Hint:
 Tokenize string into an array of words
 Change all the words to be become lowercase
 Store all the words into a HashSet
 Retrieve all the items from the HashSet and store them into the resulting string
I am new to java, I am taking an online course so everything I do know is self taught. I'm not sure how to go about this method, it is really stumping me. Can anyone offer me some ideas? Thanks
public static String getWordsOfLengthN(String originalString, int wordLegth) {
Set<String> hashSet = new HashSet<String>();
String[] words = originalString.split(" ");
for (String word : words) {
if(word.length() == wordLegth) {
hashSet.add(word);
}
}
return hashSet.toString();
}

char Array difficulties

I hope the evening finds you well. My problem tonight is that I'm trying to create a char array, but I can't use any of the good ways to do it. I can only use String.length and String.charAt() my code is a miserable sad mess. This kind of combines all the things I've ever been terrible at so far.
Ultimately what I'll be trying to do is find a way to insert, delete, and replace things given certain indexes of a user-input string, but one step at a time, right?
This is what I have right now for my insert method, it's not even close to done obviously. All I'm really trying to figure out here, is how to print out my array, because when I try to print it out right now its just printing blanks. I apologize for my ineptitude.
public String insert_text(String fromtest){
System.out.println(fromtest.length());
System.out.println(fromtest);
for(int i=0;i<fromtest.length();i++){
text=new char[fromtest.charAt(i)];
System.out.println(text[i]);
}
System.out.println("* Enter the starting position:");
int startpos=k.nextInt();
System.out.println("* Enter the text you want to insert:");
String instring=k.next();
return fromtest;
}
I'm not sure why, but the prompt just say that the only things we can use are Sting.Length and String.charAt and store them to an array which I forgot to mentioned should be private char [] text.
String.toCharArray() is the function that you are looking for. It converts the String into equivalent Char array.
Convert an input String to char[] as the following sample code:
public static void main(String args[])
{
String str = "Sameer";
char[] cArray = str.toCharArray();
//Now perform functions with your charArray
}
Hope this helps.
Why can't you use
char [] input = fromtest.toCharArray(); // get's the character array as called...
if you can't use toCharArray you could try
char [] array = new char[fromtest.length()];
for (int i = 0; i < fromtest.length(); i++) {
array[i] = fromtest.charAt(i);
}
You can print each char by :
System.out.println(fromtest.charAt(i));
public String insert_text(String fromtest){
Char[] charArray = fromtest.toCharArray();
// do whateveryou want;
return fromtest;
}
So far i understand your problem is you need to make dynamic array of what String is passed in this function,
use char[] charArray = string.toCharArray();
but what you are doing i prefer you stack and queues

Determining if a given string of words has words greater than 5 letters long

So, I'm in need of help on my homework assignment. Here's the question:
Write a static method, getBigWords, that gets a String parameter and returns an array whose elements are the words in the parameter that contain more than 5 letters. (A word is defined as a contiguous sequence of letters.) So, given a String like "There are 87,000,000 people in Canada", getBigWords would return an array of two elements, "people" and "Canada".
What I have so far:
public static getBigWords(String sentence)
{
String[] a = new String;
String[] split = sentence.split("\\s");
for(int i = 0; i < split.length; i++)
{
if(split[i].length => 5)
{
a.add(split[i]);
}
}
return a;
}
I don't want an answer, just a means to guide me in the right direction. I'm a novice at programming, so it's difficult for me to figure out what exactly I'm doing wrong.
EDIT:
I've now modified my method to:
public static String[] getBigWords(String sentence)
{
ArrayList<String> result = new ArrayList<String>();
String[] split = sentence.split("\\s+");
for(int i = 0; i < split.length; i++)
{
if(split[i].length() > 5)
{
if(split[i].matches("[a-zA-Z]+"))
{
result.add(split[i]);
}
}
}
return result.toArray(new String[0]);
}
It prints out the results I want, but the online software I use to turn in the assignment, still says I'm doing something wrong. More specifically, it states:
Edith de Stance states:
⇒     You might want to use: +=
⇒     You might want to use: ==
⇒     You might want to use: +
not really sure what that means....
The main problem is that you can't have an array that makes itself bigger as you add elements.
You have 2 options:
ArrayList (basically a variable-length array).
Make an array guaranteed to be bigger.
Also, some notes:
The definition of an array needs to look like:
int size = ...; // V- note the square brackets here
String[] a = new String[size];
Arrays don't have an add method, you need to keep track of the index yourself.
You're currently only splitting on spaces, so 87,000,000 will also match. You could validate the string manually to ensure it consists of only letters.
It's >=, not =>.
I believe the function needs to return an array:
public static String[] getBigWords(String sentence)
It actually needs to return something:
return result.toArray(new String[0]);
rather than
return null;
The "You might want to use" suggestions points to that you might have to process the array character by character.
First, try and print out all the elements in your split array. Remember, you do only want you look at words. So, examine if this is the case by printing out each element of the split array inside your for loop. (I'm suspecting you will get a false positive at the moment)
Also, you need to revisit your books on arrays in Java. You can not dynamically add elements to an array. So, you will need a different data structure to be able to use an add() method. An ArrayList of Strings would help you here.
split your string on bases of white space, it will return an array. You can check the length of each word by iterating on that array.
you can split string though this way myString.split("\\s+");
Try this...
public static String[] getBigWords(String sentence)
{
java.util.ArrayList<String> result = new java.util.ArrayList<String>();
String[] split = sentence.split("\\s+");
for(int i = 0; i < split.length; i++)
{
if(split[i].length() > 5)
{
if(split[i].matches("[a-zA-Z]+"))
{
result.add(split[i]);
}
if (split[i].matches("[a-zA-Z]+,"))
{
String temp = "";
for(int j = 0; j < split[i].length(); j++)
{
if((split[i].charAt(j))!=((char)','))
{
temp += split[i].charAt(j);
//System.out.print(split[i].charAt(j) + "|");
}
}
result.add(temp);
}
}
}
return result.toArray(new String[0]);
}
Whet you have done is correct but you can't you add method in array. You should set like a[position]= spilt[i]; if you want to ignore number then check by Float.isNumber() method.
Your logic is valid, but you have some syntax issues. If you are not using an IDE like Eclipse that shows you syntax errors, try commenting out lines to pinpoint which ones are syntactically incorrect. I want to also tell you that once an array is created its length cannot change. Hopefully that sets you off in the right directions.
Apart from syntax errors at String array declaration should be like new String[n]
and add method will not be there in Array hence you should use like
a[i] = split[i];
You need to add another condition along with length condition to check that the given word have all letters this can be done in 2 ways
first way is to use Character.isLetter() method and second way is create regular expression
to check string have only letter. google it for regular expression and use matcher to match like the below
Pattern pattern=Pattern.compile();
Matcher matcher=pattern.matcher();
Final point is use another counter (let say j=0) to store output values and increment this counter as and when you store string in the array.
a[j++] = split[i];
I would use a string tokenizer (string tokenizer class in java)
Iterate through each entry and if the string length is more than 4 (or whatever you need) add to the array you are returning.
You said no code, so... (This is like 5 lines of code)

Splitting string N into N/X strings

I would like some guidance on how to split a string into N number of separate strings based on a arithmetical operation; for example string.length()/300.
I am aware of ways to do it with delimiters such as
testString.split(",");
but how does one uses greedy/reluctant/possessive quantifiers with the split method?
Update: As per request a similar example of what am looking to achieve;
String X = "32028783836295C75546F7272656E745C756E742E657865000032002E002E005C0"
Resulting in X/3 (more or less... done by hand)
X[0] = 32028783836295C75546F
X[1] = 6E745C756E742E6578650
x[2] = 65000032002E002E005C0
Dont worry about explaining how to put it into the array, I have no problem with that, only on how to split without using a delimiter, but an arithmetic operation
You could do that by splitting on (?<=\G.{5}) whereby the string aaaaabbbbbccccceeeeefff would be split into the following parts:
aaaaa
bbbbb
ccccc
eeeee
fff
The \G matches the (zero-width) position where the previous match occurred. Initially, \G starts at the beginning of the string. Note that by default the . meta char does not match line breaks, so if you want it to match every character, enable DOT-ALL: (?s)(?<=\G.{5}).
A demo:
class Main {
public static void main(String[] args) {
int N = 5;
String text = "aaaaabbbbbccccceeeeefff";
String[] tokens = text.split("(?<=\\G.{" + N + "})");
for(String t : tokens) {
System.out.println(t);
}
}
}
which can be tested online here: http://ideone.com/q6dVB
EDIT
Since you asked for documentation on regex, here are the specific tutorials for the topics the suggested regex contains:
\G, see: http://www.regular-expressions.info/continue.html
(?<=...), see: http://www.regular-expressions.info/lookaround.html
{...}, see: http://www.regular-expressions.info/repeat.html
If there's a fixed length that you want each String to be, you can use Guava's Splitter:
int length = string.length() / 300;
Iterable<String> splitStrings = Splitter.fixedLength(length).split(string);
Each String in splitStrings with the possible exception of the last will have a length of length. The last may have a length between 1 and length.
Note that unlike String.split, which first builds an ArrayList<String> and then uses toArray() on that to produce the final String[] result, Guava's Splitter is lazy and doesn't do anything with the input string when split is called. The actual splitting and returning of strings is done as you iterate through the resulting Iterable. This allows you to just iterate over the results without allocating a data structure and storing them all or to copy them into any kind of Collection you want without going through the intermediate ArrayList and String[]. Depending on what you want to do with the results, this can be considerably more efficient. It's also much more clear what you're doing than with a regex.
How about plain old String.substring? It's memory friendly (as it reuses the original char array).
well, I think this is probably as efficient a way to do this as any other.
int N=300;
int sublen = testString.length()/N;
String[] subs = new String[N];
for(int i=0; i<testString.length(); i+=sublen){
subs[i] = testString.substring(i,i+sublen);
}
You can do it faster if you need the items as a char[] array rather as individual Strings - depending on how you need to use the results - e.g. using testString.toCharArray()
Dunno, you'll probably need a method that takes string and int times and returns a list of strings. Pseudo code (haven't checked if it works or not):
public String[] splintInto(String splitString, int parts)
{
int dlength = splitString.length/parts
ArrayList<String> retVal = new ArrayList<String>()
for(i=0; i<splitString.length;i+=dlength)
{
retVal.add(splitString.substring(i,i+dlength)
}
return retVal.toArray()
}

Categories