The method has to receive a String in format "[1,2,3,4,5]" with just integers inside, but it can also have "[1,2,3,[]]" or "[1,2,3,[1,2,3]]". I already have the code to just add the numbers to the list, but I can't figure out how to handle when I have another List inside.
I've thought of having a class List and when I find another brackets inside to call the function again, but don't know how to substring correctly when I see another opening bracket [.
After I remove the brackets I split the string like this:
String[] arr = string.split(",");
And start to add those results to the List I have to return with a for loop, my problem is when I see an opening bracket again [ I would have to substring and call with the resulting String my method again but don't know how to determine the closing bracket. What I've tried is to get the index of a closing bracket with indexOf:
String aux = arr[i];
int closingBracket = aux.indexOf("]");
But if I have an input string like [1,2,3,4,[,6] which shouldn't be accepted it will accept it.
What you need to do is figure out, on paper, what is called a finite state machine (FSM). When you encounter a token (comma, bracket, digit) you enter a particular state. Once in a certain state, you can only accept certain other tokens which may put you in a different state or leave you in the current one. You could have many different states which can accept different tokens and perform different actions.
For example.
When you see a digit, the next token may be.
1. Another digit
2. A closing bracket.
3. A comma.
Each of those tokens may prompt a different state and/or action.
1. Another digit - keep on processing since numbers have many digits.
2. closing bracket - save the number in a list and get the next list (See below)
3. comma - save the number and look for next number
Assuming you want to save all of this in a list of lists it would be easiest to start off with a List<Object> since you can save integers and lists of lists in that type of list with indefinite depths.
I also suggest you look at the Stack class. You may want to be pushing the current list and popping a recent one as your parsing depth changes.
Finally, to ensure your brackets are properly matched to the following. Increment a counter when you see a '[' and decrement the counter when you see a ']'. If the counter ever goes negative, you have too many right brackets. If at the end it is positive, you don't have enough right brackets.
For more on this check out Finite State Machines at Wikipedia.
I decided to include a small example of what I was talking about. It may not cover all possible edge cases but the purpose is illustrative.
public static void main(String[] args) {
String strlist =
"[1,2,113], [4,5,[5,2,10],1], [],[1,2,3,4,5,[10,11,12,13,[14,15]]]";
int bracketCount = 0;
int num = 0;
// inital list
List<Object> list = new ArrayList<>();
// hold sublists for precessing
Stack<List<Object>> stack = new Stack<>();
char[] chars = strlist.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
switch (c) {
// state1 left bracket - push current list on stack for later
// retrieval
// allocate new list and add it to one just pushed (remember,
// I still have its reference).
// Assign nlist to list
// increment bracket count
case '[':
stack.push(list);
List<Object> nlist = new ArrayList<>();
list.add(nlist);
list = nlist;
bracketCount++;
break;
// state2 right bracket - Finished processing current sublist.
// if previous tokens were not brackets, then add the
// number to the list and pop off the previous one.
// decrement bracket count
case ']':
if (chars[i - 1] != '[' && chars[i - 1] != ']') {
list.add(num);
}
list = stack.pop();
bracketCount--;
break;
// state3 - whitespace - ignore
case ' ':
case '\t':
break;
// state4 comma - if previous token was not a right bracket,
// then add number. Reset num for next number.
case ',':
if (chars[i - 1] != ']') {
list.add(num);
}
num = 0;
break;
// state5 digit - assumed to be a digit. Each time a digit
// is encountered, update the number
default:
num = num * 10 + c - '0';
}
if (bracketCount < 0) {
System.out.println("too many ] brackets at location " + i);
}
}
if (bracketCount > 0) {
System.out.println("insufficent number of ] brackets");
}
System.out.println(list);
}
}
Note that in the above example, the "states" are rather "pseudo states." That is you don't need to check the current state you are in in order to determine how to process the current token or flag an error.
Related
I want to delete specified data in an arraylist from another class based on what the user input
so when the user input Rice, the data with 'Rice' in it will be deleted
this is the code so far
the data is stored in ArrayList rm in a subclass named RegularMenu.
ArrayList<RegularMenu> rm = new ArrayList<RegularMenu>();
Quiz1(){
int input;
do{
System.out.println("1. Add Regular Menu");
System.out.println("2. Add Special Menu");
System.out.println("3. Show All Menu");
System.out.println("4. Delete Regular Menu");
System.out.println("5. Delete Special Menu");
System.out.println("6. Exit" + "\n");
System.out.print("Choice [1-6] ");
Scanner s = new Scanner(System.in);
input = s.nextInt();
if (input == 1 ){
String code, name;
int price;
System.out.println("Add Regular Menu");
System.out.print("Input Menu Code [R...]: ");
s.nextLine();
code = s.nextLine();
System.out.print("Input Menu Name [5-20]: ");
name = s.nextLine();
System.out.print("Input Menu Price [10000-130000]: ");
price = s.nextInt();
rm.add(new RegularMenu(code, name, price));
}
else if (input == 2){
}
else if (input == 3){
}
else if (input == 4){
System.out.println("Input menu code you want to delete");
String a = s.nextLine();
for(int i=0;i<rm.size();i++){
if(a == rm.get(i).getCode()){
String code = rm.get(i).getCode();
a = code;
rm.remove(a);
}
}
}
else if (input == 5){
}
}while(input != 6);
}
i can add the data, but when try to remove it, the error occurred.
Let me know if I'm not clear enough.
The problem is that you are using List.remove(Object) wrong instead of List.remove(int).
List.remove(Object)
boolean remove(Object o)
Removes the first occurrence of the specified element from this list, if it is present (optional operation). [...] More formally, removes the element with the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))) [...]
Trying to remove a RegularMenu with a String instance won't work because a String instance can't compare itself with a RegularMenu, so it will never be equivalent. (It will use String.equals(RegularMenu) method to find where is the instance to remove.
If you want to use List.remove(Object), pass the instance itself :
rm.remove(rm.get(i));
Note:
that this will remove the first occurrence only, so if you have two "equivalent" instances, only the first one will be removed.
List.remove(Object) will search for the index where the instance passed is using Object.equals to remove by index. But in your case you already did the job with if(a == rm.get(i).getCode()) (incorrectly, see "String comparison"),
List.remove(int)
E remove(int index)
Removes the element at the specified position in this list (optional operation). Shifts any subsequent elements to the left (subtracts one from their indices) [...]
Since you know the index, you can use rm.remove(i) (List.remove(int)) to remove the value at the current index.
Careful with the index that way, the right part of the list with shift on the left. See Lajos Arpad's answer for more information
Iterator
Another solution to remove items from an ArrayList is to use the iterator. You get the Iterator and iterate every items in it. Then if one match you call Iterator.remove to remove properly the item. You can even stop the loop if you only want to remove one item
Sample data :
List<String> datas = new ArrayList<>();
datas.add("foo");
datas.add("bar");
datas.add("bar");
datas.add("foo");
datas.add("bar");
datas.add("bar");
Code :
Iterator<String> it = datas.iterator();
String s;
while(it.hasNext()){
s = it.next();
if("foo".equals(s)){
it.remove();
}
}
System.out.println(datas);
[bar, bar, bar, bar]
I precise using ArrayList because some Collection don't implements the method remove for the Iterator giving an Exception.
Predicate - removeIf
Since Java 8, Collection.removeIf exists and allows you to do a quicker solution (using the same sample data) :
final String a = "foo";
datas.removeIf(s -> a.equals(s));
System.out.println(datas);
[bar, bar, bar, bar]
It will iterate and check for each instance of RegularMenu in it if the Predicate passed will be true, if so, the item will be removed.
String comparison
Also, note the comparison "foo".equals(s) instead of "foo" == s.
More information in How do I compare strings in Java?
You can iterate your array list with a loop and remove all matches:
for (int i = 0; i < yourArrayList.size(); i ++) {
if(a.equals(rm.get(i).getCode())){
yourArrayList.remove(i--);
}
}
Your mistake was that you tried to remove a from the ArrayList using remove, but remove expects an int, representing the index to be removed. In my code notice that I am decrementing i after removing to be able to remove consequent matches.
You can remove elements from List by index
for(int i=rm.size()-1; i>=0; i--) {
// you are deleting elements from the list while iterating,
// thus it is better to iterate backwards (rm.size()..0):
if(a.trim().equals(rm.get(i).getCode().trim())) {
rm.remove(i);
}
}
Note: when you delete an element under index i, all elements to the right (i+1, ...) will be moved to the left for one position.
Thus, when iterating from left to right and deleting elements, you will be messing with indices.
On the other hand, when you are iterating from right to left and deleting something at position i, all elements to to right will still be moved one position to the left, but It does not matter for you, because you will not iterate on them.
aaaaBcccc -> aaaacccc
^ ^ ^ ^
0.. i 0.. i
for(int i=0;i<rm.size();i++) {
if(a.trim().equals(rm.get(i).getCode())) {
rm.remove(i);
break;
}
}
In the list, you can remove elements by using index.
Find below code :
for(RegularMenu regularMenu:rm){
if(a.equalsIgnoreCase(regularMenu.getCode())){
rm.remove(regularMenu);
break;
}
So, I posted this nearly identical code yesterday, asking about how to leave the punctuation at the end of a reversed sentence after using .split. I'm still struggling with it, but I'm also having another issue with the same code: And here is my screen shot http://i.stack.imgur.com/peiEA.png
import java.util.Scanner;
import java.util.StringTokenizer; // for splitting
public class MyTokenTester
{
public static void main(String\[\] args)
{
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String\[\] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
for (int count = words.length -1; count>=0; count--) // reverse the order and assign backward each token
{
backward += words\[count\] + " ";
}
System.out.println(backward); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
sentinel = sentinel.toLowerCase(); // regardless of case
} while (!sentinel.equals("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
} // end class MyTokenTester][1]][1]
As you guys can probably see my from screen shot, when the user is prompted to add another sentence in, the previous sentence is read back again.
My questions are:
How do I use charAt to identify a character at an undefined index (user input with varying lengths)
How do I stop my sentence from reading back after the user decides to continue.
Again, as I said, I'd posted this code yesterday, but the thread died and I had additional issues which weren't mentioned in the original post.
To address part 2, if you want to stop the sentence from reading back previous input, then reset backward to an empty string, because as it stands now, you're constantly adding new words to the variable. So to fix this, add this line of code right before the end of your do-while loop,
backward = "";
To address part 1, if you want to check the last character in a string, then first you have to know what is the last index of this string. Well, a string has indexes from 0 to str.length()-1. So if you want to access the very last character in the user input, simply access the last word in your words array (indexed from 0 to words.length - 1) by doing the following,
words[count].charAt(words[count].length() - 1);
Note that count is simply words.length - 1 so this can be changed to your liking.
1) So you have this array of strings words. Before adding each word to the backward string, you can use something like: words[count].chartAt(words[count].length() - 1). It will return you the charater at the last position of this word. Now you are able to do you checking to know wether it is a letter or any special char.
2) The problem is not that it is reading the previous line again, the problem is that the backward string still has the previous result. As you are using a + operator to set the values of the string, it will keep adding it together with the previous result. You should clean it before processing the other input to have the result that you want.
here is your code:
import java.util.*;
public class main{
public static void main(String[] args){
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String[] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
List<String> items = Arrays.asList(words);
Collections.reverse(items);
System.out.println(generateBackWardResult(items)); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
// i use quals ignore case, makes the code more readable
} while (!sentinel.equalsIgnoreCase("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
static String generateBackWardResult(List<String> input){
String result="";
for (String word:input){
result =result +" "+word;
}
return result;
}
} // end class MyTokenTester][1]][1]
there are also some thing to mention:
* never invent the wheel again! (for reverting an array there are lots of approaches in java util packages, use them.)
*write clean code, do each functionality, i a separate method. in your case you are doing the reverting and showing the result in a single method.
I'm stuck on creating a program to solve a question for a class. I have a main method and a secondary testing method that are working in conjunction to solve this problem, however I can't get the solution to work when there's a change.
The problem is making sure a word is square free, here's an excerpt from the problem:
For this part, implement a method called isSquareFree that takes as input (a reference to ) an array of characters. You may assume that the elements of the array are all lower case letters. (In other words, you do not need to worry about a question like: "is Z the same letter as z?") Your method should test if the given input array of characters is square-free. If it is, the method should print a message stating that, otherwise it should print a message stating that the world is not square-free, where the square subword starts and what that subword is. For example, if the given array contained the word zatabracabrac the method should print: The word, zatabracabrac, is not square free, since it has subword, abrac twice starting at position 4 of the word.
Below is the current code I have, it works in the case that there is a repeating character directly next to each other, but I'm unsure of how to continue to check if there is multiple repeating characters (abab for example) nor am I sure how to print out the repeating subword.
public static void main(String[] args) {
// part (a) of the main
Scanner keyboard = new Scanner(System.in);
System.out.println("***************************");
System.out.println(" Part (a)");
System.out.println("***************************");
do{
System.out.println("Enter a word and then press enter:");
String str=keyboard.next();
char[] word = str.toCharArray();
isSquareFree(word);
System.out.println("Do you want to test another word? Press y for yes, or another key for no");
}while(keyboard.next().charAt(0)=='y');
}
public static void isSquareFree(char[] word){
int sqf = 0;
for(int i=0; i<word.length; i++){
for(int j=0; j<word.length-1;j++){
if (word[j] == word[j+1]){
sqf = 1;
j = word.length;
}
else{
sqf = 2;
}
}
}
if (sqf == 1){
System.out.println();
System.out.println("Not Square Free");
}
else{
System.out.println();
System.out.println("Square Free");
}
}}
I'd also like to add that I'm not allowed to use the arrays class for this question, nor am I allowed to use strings and I cannot change the main method, not can I change the input for my other method.
To see if a sequence of characters repeats, for a given sequence length (say, n), you would replace your if with a loop that compares word[j+x] with word[j+n+x] for each value of x between 0 and n; and only consider them the same if all n match. Thus, you'd need to loop over these n values for x; if you need to consider different values of n, then you'd need yet another loop to go through those.
It isn't clear from your code what you are using i for, but if it is the length of the repeating part (what I've called n), then you'd only need to consider values up to half the length of word (or else there isn't room to repeat it).
To print out a sub word, you could print out each individual letter in order (using print instead of println)
I'm writing a program that applies many principles of computational linguistics. My problem at this moment is the following piece of code form a method that "flexibilizes two definitions". This is, it compares two different definitions of the same word, and in each definition empty or blank spaces will be added to later on work with the altered definitions (with blank spaces added).
Say we have the following two definitions, defining the term "free fall".
1) Free fall descent of a body subjected only to the action of gravity.
2) Free fall movement of a body in a gravitational field under the influence of gravity
There is a list of words called stoplist, which contains the words: "of", "a", "in", "to", and "under". After the process, each word in the definition that is also contained in the stoplist must correspond to a blank space OR another stoplist word of the other definition. So after executing such process, the previous definitions, represented in two different lists, should look like this:
1) Free fall descent of a body ____ ____ subjected only to the action of gravity.
2) Free fall movement of a body in a gravitational field under the influence of gravity.
The code I wrote to achieve this is the following:
[...]
String[] sList = STOPLIST.split(" "); //this is the stoplist
String[] definition1 = defA1.split(" "); //this is the array of words of the first definition
String[] definition2 = defA2.split(" "); //this is the array of words of the second definition
List<String> def1 = new ArrayList<String>();
List<String> def2 = new ArrayList<String>();
List<String> stopList = new ArrayList<String>();
for(String word : definition1){
def1.add(word); //I transform arrays into lists this way because I used to think that using .asList() was the problem.
}
for(String word : definition2){
def2.add(word);
}
for(String word : sList){
stopList.add(word);
}
int mdef = (def1.size() <= def2.size()) ? def1.size() : def2.size(); //here mdef will have the value of the lenght of the shortest definition, and we are going to use the value of mdef to iterate later on.
for(int i = 0; i < mdef; i++){
if (stopList.contains(def1.get(i))) { //here I check if the first word of the first definition is also found in the stoplist.
if (!stopList.contains(def2.get(i))) { //If the word of def1 previously checked is in the stoplist, as well as the corresponding word in the second definition, then we won't add a " "(blank) space in the corresponding position of the second definition.
def2.add(i , " "); //here I add that blank space, only if the stoplist word in def1 corresponds to a non-stoplist word in def2. Again, we do this so the stoplist word in def1 corresponds to a blank space OR another stoplist word in def2.
if(mdef == def2.size())
mdef++; //In case the shortest definition is the definition to which we just added spaces, we increment mdef++, because that space added increases the length of the shortest definition, and to iterate in this recenlty extended definiton, we have to increment the index with which we iterate.
}
} else if (stopList.contains(def2.get(i))) { //this else if does the same than the previous one, but checks for the second definition instead of the first one. And adds blanks to def1 instead of def2 if necessary.
if (!stopList.contains(def1.get(i))) {
def1.add(i , " ");
if(mdef == def1.size())
mdef++;
}
}
}
[...]
Now, if you analyze the code carefully, you will realize that not all words of the lengthiest list will be checked, given that we iterate ove the definitions using the lenght of the shortest definition as index. This is fine, the remainding words of the lenghtiest definitions don't have to be checked, they will correspond to null spaces of the other definition (in case the lists don't end up being of the same lenght after the addition of spaces, as the previous exaple shows).
Now, after the explanation, the problem is the following: after running the main class, which calls the method that contains the previous code, a runtime exceptions pops out:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:571)
at java.util.ArrayList.get(ArrayList.java:349)
at main2.main(main2.java:75)
I don't understand why it is finding any of the lists as "empty". I have tried to solve it in too many ways, I hope a I gave a good explanation.
It may help as a clue that if I assign mdef to the lengthiest size instead of the shortest, that is :
int mdef = (def1.size() >= def2.size()) ? def1.size() : def2.size();
the error changes to:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 15, Size: 15
at java.util.ArrayList.rangeCheck(ArrayList.java:571)
at java.util.ArrayList.get(ArrayList.java:349)
at asmethods.lcc.turnIntoFlex(lcc.java:55)
at asmethods.lcc.calLcc(lcc.java:99)
at main2.main(main2.java:73)'
Where lcc is the class that contains the method turnIntoFlex that contains the piece of code I'm showing. The line 55 of "turnIntoFlex" corresponds to the first line of the loop, that is:
if (stopList.contains(def1.get(i))) { [...]
Comments: The values of defA1 and defA2 are the definitions, respectively. i.e. def1 and def2, initially, are lists in which each separate element is a word. I can't check if these lists are being populated by printing them because the indexoutofboundsexception pops at the very moment the loop starts. However, I do print the values of the sizes of mdef, def1.size() and def2.size(), and the values turn out to be 13, or 15, showing that no list is empty before the "for" loop starts.
The mdef++ was something I added recently, not to exactly to solve this specific problem, but the error has been popping since before I added the mdef++ part. As I explained, The intention is to increase mdef++ when the shortest list is extended (but only when the short list is extended) so we iterate through all the words of the short list, and not more.
One issue with your code is that when you increment mdef you do not check to see if it now exceeds the length of the other list.
For example, suppose def1 had 3 words and def2 had 4 words. mdef would start at 3. But then suppose you successively add two spaces to def1 and increment mdef twice to be 5. This now exceeds the length of def2 and will then cause an index out of bounds exception in the def2 else condition if you keep iterating up to 5.
Added later:
Another serious issue with your code (that I thought of later) is that when you add the space to a list (either def1 or def2) this shifts the indices of all of the subsequent elements up by 1. So, for example, if you add a space at spot 0 in def1 when i is 0, then on the next pass through the loop, having incremented i to 1, you will look at the same word in def1 that you looked at in the previous pass. This is probably the source of some of your exceptions (as it would lead to a continual loop until you exceed the length of the other list: problem #1 above).
To correct both of these issues, you would need to change your code to something like:
int i = 0;
int j = 0;
while (i < def1.size() && j < def2.size()) {
if (stopList.contains(def1.get(i)) && !stopList.contains(def2.get(j)))
def2.add(j++, " ");
else if (stopList.contains(def2.get(j)) && !stopList.contains(def1.get(i)))
def1.add(i++, " ");
++i;
++j;
}
Note that you don't ned mdef any more in this implementation.
Man, I think I got it. I modified the code, but I hope you understand what I did:
static public void main(String[] argv) {
String[] sList = "of a in to under".split(" ");
String[] definition1 = "Free fall descent of a body subjected only to the action of gravity"
.split(" ");
String[] definition2 = "Free fall movement of a body in a gravitational field under the influence of gravity"
.split(" ");
List<String> def1 = new ArrayList<String>();
List<String> def2 = new ArrayList<String>();
List<String> stopList = new ArrayList<String>();
for (String word : definition1) {
def1.add(word);
}
for (String word : definition2) {
def2.add(word);
}
for (String word : sList) {
stopList.add(word);
}
int mdef = (def1.size() <= def2.size()) ? def1.size() : def2.size(); // Shortest
// length
for (int i = 0; i < mdef; i++) {
System.out.println(i);
if (!stopList.contains(def1.get(i)) && !stopList.contains(def2.get(i))) {
continue;
}
else if (stopList.contains(def1.get(i)) && stopList.contains(def2.get(i))) {
continue;
}
else if (!stopList.contains(def1.get(i)) && stopList.contains(def2.get(i))) {
def1.add(i, " ");
mdef = (def1.size() <= def2.size()) ? def1.size() : def2.size(); // define mdef again
}
else if (stopList.contains(def1.get(i)) && !stopList.contains(def2.get(i))) {
def2.add(i, " ");
mdef = (def1.size() <= def2.size()) ? def1.size() : def2.size(); // define mdef again
}
}
for (String word : def1) {
if (word.equals(" "))
System.out.print("_ ");
else
System.out.print(word+" ");
}
System.out.println();
for (String word : def2) {
if (word.equals(" "))
System.out.print("_ ");
else
System.out.print(word+" ");
}
}
Is this the exact code you're using? I just ran it and it worked fine, I used:
import java.util.*;
public class HelloWorld {
public static void main(String []args) {
String stoplist= "of a in to and under";
String defA1 = "Free fall descent of a body subjected only to the action of gravity";
String defA2 = "Free fall movement of a body in a gravitational field under the influence of gravity";
String[] sList = stoplist.split(" "); //this is the stoplist
String[] definition1 = defA1.split(" "); //this is the array of words of the first definition
String[] definition2 = defA2.split(" "); //this is the array of words of the second definition
List<String> def1 = new ArrayList<String>();
List<String> def2 = new ArrayList<String>();
List<String> stopList = new ArrayList<String>();
for (String word : definition1) {
def1.add(word); //I transform arrays into lists this way because I used to think that using .asList() was the problem.
}
for (String word : definition2) {
def2.add(word);
}
for (String word : sList) {
stopList.add(word);
}
int mdef = (def1.size() <= def2.size()) ? def1.size() : def2.size(); //here mdef will have the value of the lenght of the shortest definition, and we are going to use the value of mdef to iterate later on.
for (int i = 0; i < mdef; i++) {
if (stopList.contains(def1.get(i))) { //here I check if the first word of the first definition is also found in the stoplist.
if (!stopList.contains(def2.get(i))) { //If the word of def1 previously checked is in the stoplist, as well as the corresponding word in the second definition, then we won't add a " "(blank) space in the corresponding position of the second definition.
def2.add(i , " "); //here I add that blank space, only if the stoplist word in def1 corresponds to a non-stoplist word in def2. Again, we do this so the stoplist word in def1 corresponds to a blank space OR another stoplist word in def2.
if (mdef == def2.size())
mdef++; //In case the shortest definition is the definition to which we just added spaces, we increment mdef++, because that space added increases the length of the shortest definition, and to iterate in this recenlty extended definiton, we have to increment the index with which we iterate.
}
} else if (stopList.contains(def2.get(i))) { //this else if does the same than the previous one, but checks for the second definition instead of the first one. And adds blanks to def1 instead of def2 if necessary.
if (!stopList.contains(def1.get(i))) {
def1.add(i , " ");
if (mdef == def1.size())
mdef++;
}
}
}
for (String word : def1) {
System.out.print(word+",");
}
System.out.println();
for (String word : def2) {
System.out.print(word+",");
}
}
}
Instructions:
Write a program that will read a line of text that ends
with a period, which serves as a sentinel value. Display all the
letters that occur in the text, one per line and in alphabetical
order, along with the number of times each letter occurs in the text.
Use an array of base type int of length 26 so that the element at
index 0 contains the number of as. and index 1 contain number of bs etc.
package alphabetize;
import java.util.*;
public class Alphabetize
{
private static void number(String s)
{
int[] array = new int[26];
s = s.toUpperCase();
System.out.println(s);
for (int i = 0; i < s.length(); ++i)
{
if (s.charAt(i) >= 'A' && s.charAt(i) <= 'Z')
{
++array[s.charAt(i) - 'A'];
}
}
for (int i = 0; i < 26; ++i)
{
System.out.println("|" + (char) ('A' + i) + "|" + array[i] + "|");
}
}
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
String aString = ".";
while (true)
{
System.out.println("Please enter sentence with a period to end");
aString = keyboard.nextLine();
if (".".equals(aString))
{
System.exit(0);
}
number(aString);
}
}
}
Still having problem with the period thing.. it does not seem to work the way i did it.
Considering this is a homework and instructions are very specific, you should read the text character by character instead of using built-in functions
If your text file was something like
abcabca.
The output should be something a appears three times, b appears two times etc etc.
So your algo should be something like
Read next character
If char is period goto 5
If char is space goto 1.
If char is between a <-> z. update the counter in arr[0..25] and goto 1
output arr[0..25] one per line
Was it mandated that this assignment is done in Java? The whole idea of a "sentinal character" rather than just using a line terminator is pretty bizarre.
Anyway, you can achieve the behaviour you want by setting the delimiter of Scanner:
keyboard.useDelimiter("\\.");
As for the looping, a big hint is this:
int[] counts;
counts[chars[0] - 'a'] = counts[chars[0] - 'a'] + 1;
or simply
counts[chars[0] - 'a']++;
I'll leave it up to you to include that in a loop.
Edit
If you are looking for character-at-a-time input, I would suggest you use an InputStreamReader instead of Scanner for your input. Here's a basic skeleton of what that looks like:
Reader reader = new InputStreamReader(System.in);
while (true) {
int nextInput = reader.read();
if (nextInput == -1) {
System.out.println("End of input reached without sentinal character");
break;
}
char nextChar = (char) nextInput;
//deal with next character
}
Still, read() will typically block until either the end of input is reached (CTRL-D or CTRL-Z from most consoles) or a new line is sent. Thus the sentinal character is of limited use since you still have to do something after typing ".".
You have to check whether period is there at the end or not. So the last character should be '.'.
Then take the length of string before last '.'.
For the counting part create an array like u are doing :
int [] name = new int[26]
where each index starting from 0, 25 corresponds to 'a' till 'z'.
Now you put the string characters in a loop and have to check what that character is like :
if its a 'a' : increase the value at index 0 by 1.
if its a 'd' : increase the value at index 3 by 1.
like wise.
later you display the whole array with a, z along with indexes from 0 till 25.
Suggestion: If its not required to use an array, and you can use any other data-structure you can implement the same in a HashMap very easily. by keeping 'a', 'z' as the keys and count as the corresponding values. and then retrieving and showing the values will also be easier.
You need an int array (e.g., int[] counts = new int[26];) After you read the input line, examine it character by character in a loop. If the character is a not period, then increment the appropriate element of the counts array. (If the character is a, then increment counts[0]; if it is b, increment counts[1]; etc. Hint: you can subtract a from the character to get the appropriate index.) When you find a period, exit the loop and print the results (probably using a second loop).