it works in c but not in java? - java

The following code to gets the vowel deleted from array, and the array rearranges itself.
public static void main(String[] args) {
int a = 0,k=0;
Scanner obj = new Scanner(System.in);
System.out.println("enter string");
String s= obj.nextLine();
char c[]=new char[s.length()];
c = s.toCharArray();
for(int i =0; i<s.length();i++){
if(c[i]=='a'|| c[i]=='i'|| c[i]=='o'||c[i]=='u'||c[i]=='e'){
for(int j=0;j<s.length();j++){
c[j]=c[j+1];
}
}
}

In the j for loop, you have this statement:
c[j]=c[j+1];
The ArrayIndexOutOfBoundsException comes when j is the last possible index, and you attempt to access the index element one too high.
You can stop when you get to s.length() - 1.
Additionally, you are shifting everything down, not just past where you found a vowel. Start your j for loop not at 0, but at i.
for(int j=i;j<s.length() - 1;j++){
You'll also have to decide what to do with the end of the array, which is not getting overwritten with anything here.

You can't change an array by pointing one location to the next: c[j]=c[j+1]; That line will only replace the character at c[j] but it won't remove that position entirely from the array. You'd need to create a new array with the vowels removed.
This also explains the out-of-bounds exception which happens when you're at the end of the array. You're trying to access the element at j + 1 but that is outside the array.

for(int j=0;j<s.length();j++){
c[j]=c[j+1];
}
Your problem is here. c[j+1] is referencing a location beyond the end of your array. When you assign c[j] a value from that location, you're trying to retrieve a location that does not exist. This causes an ArrayOutOfBoundsException.

You can achieve the same effect by transforming the string with a RegExp:
s.replaceAll("[aioue]","");

This works in C because the size of the string with strlen is one less than the actual size including the \0 at the end. When you copy all the characters down, you are moving the termination character as well. Java doesn't use termination characters and doesn't have a character which is beyond the end of the String.
In Java it is more natural to write a regular expression like this and work with Strings from the start.
System.out.println("enter string");
Scanner scan = new Scanner(System.in);
String line = scan.nextLine();
String noVowels = line.replaceAll("[AEIOUaeiou]", "");
System.out.println("Without vowels the line is '" + noVowels + "'");
Or you can use this regex
// (?i) mean case insensitive
String noVowels = line.replaceAll("(?i)[aeiou]", "");

you have the length of string is 4 and you put it on c[s.length] mean it start from 0-3 array indexing. in the second loop you swap the c[j+1] int c[j]. it cause array index out of bounds.
try this in the second loop
for (int j = 0; j < s.length()-1; j++)
{
System.out.println(c[j+1]);
c[j] = c[j + 1];
}

Related

Java "break" seems to be breaking both nested for loops

This code reads in each line from a plain text file (each line has a "list" of arrays of integers) and basically breaks it down into single integers, which are stored in a temporary array. Each line of the document must be arranged into a 2 dimensional array with an equal number of rows and columns.
The line of code that tests a condition using an "if" statement is supposed to break ONLY the inner for loop, and go back to the outer one, increment i, and move on to the next array in that line.
So far, the code I have will take only the FIRST array in each line, place it into the FIRST row of a 2D array, but will skip all the other arrays in the line and move on to the next line, where it does the same thing. So the inner loops goes once, but the outer loop never increments. Every post I've read says that "break" in a nested for loop only exits the inner loop. That doesn't seem to be the case in this situation.
So how could I make sure that the outer loop increments and all the arrays in the line are accounted for?
if (!thisLine.equals("*")) {
String [] firstSplit = thisLine.split(" ");
String [] secondSplit = new String [firstSplit.length * firstSplit.length];
int [][] numbers = new int [firstSplit.length][firstSplit.length];
int value = 0;
int count = 0;
for (int i = 0; i < firstSplit.length; i++) {
firstSplit[i] = firstSplit[i].replace("[", "").replace("]", "");
secondSplit = firstSplit[i].split(",");
for (int j = 0; j < secondSplit.length; j++) {
value = Integer.parseInt(secondSplit[j]);
if (count >= firstSplit.length) {
break;
}
numbers[i][count] = value;
count++;
System.out.println(value);
}
}
System.out.println(Arrays.deepToString(numbers));
}
For example: there is a line in the file that reads:
[6,10,15,13] [16,2,14,7] [11,8,9,3] [5,4,1,12]
'firstSplit' would break up the line by whitespace, making an array of length 4.
Then the brackets would be removed.
For each item in firstSplit, secondSplit would break it up by commas, making an array of length 16 (of individual integers).
Each item in secondSplit would be converted to an integer and placed in an array like so:
6 at [0][0], 10 at [0][1], 15 at [0][2], 13 at [0][3].
The next array [16, 2, 14, 7] is completely ignored.
You never reset count, so once it becomes higher than firstSplit.length, every repetition after that will break immediately.
You should move the initialization of count inside the outermost for loop, so that it gets reset to 0 after each time through the inner loop.
That should fix the problem you're seeing, but there's a few other things in there which I think could be improved. Your initial declaration of secondSplit is unnecessary, since you always assign it a new value (firstSplit[i].split(",")) before you use it. I'd suggest deleting that declaration, and changing the line inside the outer loop to this: String[] secondSplit = firstSplit[i].split(",");. That will avoid needlessly allocating a chunk of memory.
Second, unless I'm not understanding your goal, you're going to encounter problems when the array width is different from it's height. You only need count because you initialize numbers[i]'s length to be firstSplit.length, rather than the actual size it needs to be. I'd change your code to this:
String [] firstSplit = thisLine.split(" ");
int [][] numbers = new int [firstSplit.length][];
for (int i = 0; i < firstSplit.length; i++) {
firstSplit[i] = firstSplit[i].replace("[", "").replace("]", "");
String[] secondSplit = firstSplit[i].split(",");
numbers[i] = new int[secondSplit.length];
for (int j = 0; j < secondSplit.length; j++) {
int value = Integer.parseInt(secondSplit[j]);
numbers[i][j] = value;
System.out.println(value);
}
}
Now it's only declaring the variables where they're actually needed, and setting the inner arrays to be the size they need.

String.split replication: OutOfBoundsException

For my CompSci class, we're making a Would You Rather? function for our chatbot project. The String.split() method works well for this, but we get bonus points if we can do it without it. I decided to go about this by just creating a method that replicated String.split.
private String[] separate (String phrase, String omit1, String omit2)
{
int c = 0;
//gets rid of leading and trailing whitespace, replaces target characters
//with the # character
phrase = phrase.trim();
phrase = phrase.replace(omit1, "#");
phrase = phrase.replace(omit2, "#");
//detects the number of phrases to be included in the array
for (int i = 0; i < phrase.length(); i++)
if (phrase.charAt(i) == '#')
c++;
//creates array list based on number of phrases
String[] phraseList = new String[c];
c = 0;
//builds phrases from characters found between occurrences
//of the # character
for (int i = 0; i < phrase.length(); i++)
{
if (phrase.charAt(i) == '#')
c++;
else if (phrase.charAt(i) != '#')
phraseList[c] += phrase.charAt(i);
}
return phraseList;
}
Whenever I use this method with the phrase "Would you rather have tea, eat cookie, or push up?" (omit1 being "," and omit2 being "or") it throws this Exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Magpie.separate(Magpie.java:306)
at Magpie.getResponse(Magpie.java:44)
at MagpieRunner.main(MagpieRunner.java:24)
I realize that this has something to do with the counter for the phraseList array, but my attempts to fix it have so far been to no avail.
Any Help?
because if you have even 1 # you will have 2 strings so you need to do c+1 while creating a new array
Like
//creates array list based on number of phrases
String[] phraseList = new String[c+1];
c = 0;
you should use replaceAll(omit1,"#") and not replace(omit1,"#") & replace(omit2,"#")
Can you give more information on where the null is coming ?
Edit:
Have you tried something like ?
phraseList[0]="";
for(int i = 0; i < phrase.length(); i++)
{
if(phrase.charAt(i) == '#')
{
c++;
phraseList[c]="";
}else if(phrase.charAt(i) != '#')
{
phraseList[c] += phrase.charAt(i);
}
}
Think of it like commas separating a list:
1 , 2 , 3 , 4 , 5 , 6
If you count the commas, you'll find there are five; but there are six entries in the list. That's because commas separate the entries, but you still have one on each end.
Or think in terms of fence posts and panels: five posts, four panels.
When you create your array to store the phrases, you need one more entry than you had split points, to make sure you have room for all the phrases.
But it would be easier to avoid this entirely and return a List<String> rather than a String[]. That way, you don't need to know the size in advance.
Since other answers showed you what's wrong with your code, here is a cleaner way of separating string that you might like and that behaves more like the actual split() method:
private String[] separate(String phrase, String delim) {
List<String> tokens = new ArrayList<String>();
// add delimiter to the end of the string
// so last token will be included properly
phrase += delim;
// start from index of first deliminator
// i is the index for the deliminator
// j is the index for the first char of the expression before deliminator
int i, j = 0;
// while there are deliminators
while( (i = phrase.indexOf(delim, j)) != -1) {
// obtain the current token from j to deliminator location
String token = phrase.substring(j, i);
// trim leading/trailing spaces of the token and make sure it has any chars
// if it does, add the token to list
if(token.trim().length() != 0) {
tokens.add(token);
}
// update j to the first character after the deliminator
j = i + delim.length();
}
return tokens.toArray(new String[0]);
}
why not use StringTokenizer? (Below is an example from Java doc)
The following is one example of the use of the tokenizer. The code:
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
prints the following output:
this
is
a
test
Arrays are indexed starting from 0, but the length of the array is determined with an initial value of 1.
So even though c gives you the number of phrases, its actually the number of indices in the array (since c starts from 0) and not the actual length. The actual length will be c + 1 (since length is calculated starting from 1)
Index 0 | 1 | 2 | 3 | 4
Length 1 | 2 | 3 | 4 | 5
For example, if c = 4 (Index = 4), your String[] will have length 4, when it should be 5. This is what throws that ArrayIndexOutOfBounds. Hope this helps :)

How to determine ASCII value of a word

I am creating a program that imports a large list of words. This list has been separated by word but I now need to determine the ASCII value of each word in this list, and eventually which one has the highest total ASCII value. I am receiving a few errors and need to know how to get this corrected so that I can get each value.
public static void main(String[] args) throws IOException {
//import list of words
BufferedReader File = new BufferedReader(new FileReader(LOC));
//Create a temporary ArrayList to store data
ArrayList<String> words = new ArrayList<String>();
//Find number of lines in txt file
String line;
String delimiter = "\t";
while ((line = File.readLine()) != null)
//read the file
{
String[] wordsInLine = line.split(delimiter);
//separate the words
for(int i=0, isize = wordsInLine.length; i < isize; i++){
words.add(wordsInLine[i]);//put them in a list
//assess each character in the word to determine the ascii value
int total = 0;
for (int i=0; i < wordsInLine.length(); i++)
Receiving an error on the above line that states - Cannot invoke length() on the array type
String[]
- Duplicate local variable i
{
char c = word.charAt(i);
Receiving an error on the above line that states word cannot be resolved
int j = (int) c;
total += c;
}
I have done some research trying to determine the best way to calculate the ASCII value of each word and I haven't been able to find much information on how to do this. If someone could please take a look at my code I would appreciate it!! Also, before anyone says it let me just say this is NOT a school project. I am on summer break and beginning programming II in the fall and just trying to keep up on coding so that I am not rusty in the fall. THANK YOU!!! :))
Receiving an error on the above line that states - Cannot invoke length() on the array type String[] - Duplicate local variable i
wordsInLine is an array, and length is property of array. So, you have to use:
wordsInLine.length
If wordsInLine was a String, then wordsInLine.length() would have made sense.
Receiving an error on the above line that states word cannot be resolved
Before the line char c = word.charAt(i);, add below:
String word = wordsInLine[i];
For the wordsInLine.length() issue, length() is not a valid method for arrays. You actually have to access the length field thusly: wordsInLine.length without ().
As for word.charAt(i), you haven't declared a variable called word anywhere which is what's causing the problem. What you really want to do is sum up the values for every word in the array, and for that you need a nested loop.
You also said that you wanted to figure out which one had the highest value. To do that, just keep track of the largest one and update it after each iteration like this:
int indexOfMax = 0;
int[] sums = new int[wordsInLine.length];
//Iterate over every word
for(int i = 0; i < wordsInLine.length; i++)
{
//Reset the total for each word
total = 0;
//Iterate over every character in the word
for(int j = 0; j < wordsInLine[i].length(); j++)
{
char c = wordsInLine[i].charAt(j);
total += c;
}
//Remember the sum for this word
sums[i] = total;
//If the word's sum is greater than our previous max,
//make it the new max
if(sums[i] > sums[indexOfMax])
{
indexOfMax = i;
}
}
And now you can get the word with the greatest ASCII value by calling wordsInLine[indexOfMax]. It will have an ASCII sum of sums[indexOfMax].
wordsInLine is an array and therefore it does not have a method to get its length. Instead, to get an array's length, use array.length as opposed to what you were doing: array.length() (which causes an error).
word is not a defined variable, this is why java is saying that it cannot be resolved (it can't find any declaration). Instead you want to use 2 for loops in order to loop over every character in the word in the array wordsInLine. You also have two instances of the variable i, this is not allowed. To fix these errors write the following code after `int total = 0;':
int total = 0; // Don't rewrite this line
int[] totals = new int[wordsInLine.length]; // If you want to add all your totals to an array
for (int j=0; j < wordsInLine.length; j++) {
total = 0;
for (int k=0; k < wordsInLine[j].length(); k++) { // Here wordsInLine[j] is a string so you use .length() instead of .length
char c = wordsInLine[j].charAt(k);
int w = (int) c; // Get ascii of c
total += w; // Add it to total
}
// Do something with the total of this word before it gets reset to 0
// Maybe add it to an array of totals:
totals[j] = total;
}
I hope this helps!
Well your organization of your code needs a little bit of work.
First I would take this whole block of code outside file read in while loop.
for (int i=0; i < wordsInLine.length(); i++)
{
char c = word.charAt(i);
int j = (int) c;
total += c;
}
Why? Lets split what you are doing into two steps. Read in all the words into the word list. After doing this you will find where your core root of the problem is. You aren't reading the words from your word list at all.
Further code cleanup
for(int i=0, isize = wordsInLine.length; i < isize; i++){
This line is a little bit bloated. You don't need isize at all you are essentially doing denoting it for no reason. (Well actually caching the length does improve efficiency, another talk for another day). Cleaning up.
for(int i=0, ; i < wordsInLine.length; i++){
Then fixing the entire project
//import list of words
BufferedReader File = new BufferedReader(new FileReader(LOC));
//Create a temporary ArrayList to store data
ArrayList<String> words = new ArrayList<String>();
//Find number of lines in txt file
String line;
String delimiter = "\t";
// adds all the words into the list.
while ((line = File.readLine()) != null)
{
String[] wordsInLine = line.split(delimiter);
for(int i=0, ; i < wordsInLine.length; i++){
// compute alg and store the value some how to the word.
words.add(wordsInLine[i])
}
}
// notice outside the while loop.
// .size() is used for lists and .length is used for arrays.
for(int i = 0; i < words.size(); i++){
// compare
}

Avoiding duplicates without Sets?

I am in a beginner Java class and I haven't gotten the chance to learn how to avoid duplicated values when storing values inside arrays.
String[] newAlphabet = new String[26];
for(int I = 0; I < newAlphabet.length; I++){
int random = (65 + (int)(Math.random() * ((90 - 65) + 1));
char ascii = (char)random;
String letters = ascii + "";
if(letters != newAlphabet[0] && letters != newAlphabet[1] ... so on and so on until
newAlphabet[25])
newAlphabet[I] = letters;
}//end
So this is my pseudo code for part of my program and the point of it is to avoid having duplicated letters inside the array.
The problem that I am having is inside the if statement. Instead of typing letters != newAlphabet[] to 25, is there another way of doing it?
I have seen some of the forums in stackedoverflow that I should use HashSet but I have not learned that? I can ask my teacher if I am allowed but is there another way to avoid this problem?
I have been thinking of using for-each loop to search through all the elements in the array but I haven't thought out the plan long enough if it's valid.
As you are talking about a beginner Java class, I am assuming you are fairly new to programming. So, rather than just give you a library function that will do it for you, let's walk through the steps of how to do this with just the basic code so you can get a better idea of what is going on behind the scenes.
Firstly, for any repetitive action, think loops. You want to check, for each letter in your new alphabet, if the one you are about to add matches it. So...
boolean exists = false; //indicates whether we have found a match
for (int j = 0; j < 26; j++) { //for each letter in the new alphabet
//true if this one, or a previous one is a match
exists = exists || letters == newAlphabet[i];
}
//if we don't have a match, add the new letter
if (!exists) newAlphabet[I] = letters;
Now, as you are building up your new alphabet as we go, we don't have a full 26 letters for most cases of running this code, so only check the parts of the new alphabet we have defined:
boolean exists = false;
for (int j = 0; j < I; j++) { //note in this line we stop before the insertion point
exists = exists || letters == newAlphabet[i];
}
if (!exists) newAlphabet[I] = letters;
Finally, we don't need to keep checking if we have already found a match, so we can change the loop to stop when we have found a match:
boolean exists = false;
int j = 0;
while (!exists && j < I) { //we now also stop if we have already found a match
exists = letters == newAlphabet[i];
//as we are stopping at the first match,
//we no longer need to allow for previous matches
}
if (!exists) newAlphabet[I] = letters;
You could use the asList method:
if( Arrays.asList(newAlphabet).contains(letters) ) {
newAlphabet[I] = letters;
}
It's not the most efficient, but since your array is only 26 elements long, I would favor clarity over efficiency.
Some explanation: asList is a static method on the Arrays class. This just means that we don't have to create an Arrays object to call it. We simply say Arrays.asList() and pass it the arguments. The asList method takes an array (newAlhpabet in this case) as a parameter, and builds a java.util.List out of it. This means that we can call List methods on the return value. contains() is a method on List that returns true if the List contains an element that is equal to the parameter (letters in this case).
Based on this line it looks like all you're trying to do is produce the letters A to Z in some other order:
int random = (65 + (int)(Math.random() * ((90 - 65) + 1));
If I'm understanding that right, then really all you're trying to do is shuffle the alphabet:
// Initialize new alphabet array
String originalAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] newAlphabet = originalAlphabet.toCharArray();
// Shuffle the new alphabet by swapping each character to a random position
for (int i=0; i<26; i++) {
int j = (int)(Math.random() * 26);
char temp = newAlphabet[i];
newAlphabet[i] = newAlphabet[j];
newAlphabet[j] = temp;
}
// Print the new alphabet
for (int i=0; i<26; i++) {
System.out.print(newAlphabet[i]);
}
System.out.println();
Here's a sample output: VYMTBIPWHKZNGUCDLRAQFSOEJX
You have a couple options.
Loop through the array and do basically what you're doing now.
Insert the characters in sorted order so you can perform binary search to determine if a letter is already in the list. As a bonus, if you use option 2, you'll already know the insertion point.
Check out Arrays.binarySearch(): http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html
You could use this :
if(Arrays.binarySearch(newAlphabet, letters) < 0){
newAlphabet[I] = letters;
}
You should either include a while loop to make sure each index of the array is filled before moving to the next or you could make use of the return value of Arrays.binarySearch which is (-(insertion index) - 1) to fill the array and exit when the array is filled up.

Why am I getting java.lang.StringIndexOutOfBoundsException?

I want to write a program that prints words incrementally until a complete sentence appears. For example : I need to write (input), and output:
I
I need
I need to
I need to write.
Here is my code:
public static void main(String[] args) {
String sentence = "I need to write.";
int len = sentence.length();
int numSpace=0;
System.out.println(sentence);
System.out.println(len);
for(int k=0; k<len; k++){
if(sentence.charAt(k)!='\t')
continue;
numSpace++;
}
System.out.println("Found "+numSpace +"\t in the string.");
int n=1;
for (int m = 1; m <=3; m++) {
n=sentence.indexOf('\t',n-1);
System.out.println("ligne"+m+sentence.substring(0, n));
}
}
and this is what I get:
I need to write.
16
Found 0 in the string.
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -1 at
java.lang.String.substring(String.java:1937) at
split1.Split1.main(Split1.java:36) Java Result: 1 BUILD SUCCESSFUL
(total time: 0 seconds)
I don't understand why numSpace doesn't count the occurrences of spaces, nor why I don't get the correct output (even if I replace numSpace by 3 for example).
You don't have a \t character, so indexOf(..) returns -1
You try a substring from 0 to -1 - fails
The solution is to check:
if (n > -1) {
System.out.prinltn(...);
}
Your loop looking for numSpace is incorrect. You are looking for a \t which is a tab character, of which there are none in the string.
Further, when you loop in the bottom, you get an exception because you are trying to parse by that same\t, which will again return no results. The value of n in n=sentence.indexOf('\t',n-1); is going to return -1 which means "there is not last index of what you are looking for". Then you try to get an actual substring with the value of -1 which is an invalid substring, so you get an exception.
You are mistaken by the concept of \t which is an escape sequence for a horizontal tab and not for a whitespace character (space). Searching for ' ' would do the trick and find the whitespaces in your sentence.
This looks like homework, so my answer is a hint.
Hint: read the javadoc for String.indexOf paying attention to what it says about the value returned when the string / character is not found.
(In fact - even if this is not formal homework, you are clearly a Java beginner. And beginners need to learn that the javadocs are the first place to look when using an unfamiliar method.)
The easiest way to solve this I guess would be to split the String first by using the function String.split. Something like this:
static void sentence(String snt) {
String[] split = snt.split(" ");
for (int i = 0; i < split.length; i++) {
for (int j = 0; j <= i; j++) {
if (i == 1 && j == 0) System.out.print(split[j]);
else System.out.printf(" %s", split[j]);
}
}
}
As other people pointed out. You are counting every characters except tabs(\t) as a space. You need to check for spaces by
if (sentence.charAt(k) == ' ')
\t represents a tab. To look for a space, just use ' '.
.indexOf() returns -1 if it can't find a character in the string. So we keep looping until .indexOf() returns -1.
Use of continue wasn't really needed here. We increment numSpaces when we encounter a space.
System.out.format is useful when we want to mix literal strings and variables. No ugly +s needed.
String sentence = "I need to write.";
int len = sentence.length();
int numSpace = 0;
for (int k = 0; k < len; k++) {
if (sentence.charAt(k) == ' ') {
numSpace++;
}
}
System.out.format("Found %s in the string.\n", numSpace);
int index = sentence.indexOf(' ');
while(index > -1) {
System.out.println(sentence.substring(0, index));
index = sentence.indexOf(' ', index + 1);
}
System.out.println(sentence);
}
Try this, it should pretty much do what you want. I figure you have already finished this so I just made the code real fast. Read the comments for the reasons behind the code.
public static void main(String[] args) {
String sentence = "I need to write.";
int len = sentence.length();
String[] broken = sentence.split(" "); //Doing this instead of the counting of characters is just easier...
/*
* The split method makes it where it populates the array based on either side of a " "
* (blank space) so at the array index of 0 would be 'I' at 1 would be "need", etc.
*/
boolean done = false;
int n = 0;
while (!done) { // While done is false do the below
for (int i = 0; i <= n; i++) { //This prints out the below however many times the count of 'n' is.
/*
* The reason behind this is so that it will print just 'I' the first time when
* 'n' is 0 (because it only prints once starting at 0, which is 'I') but when 'n' is
* 1 it goes through twice making it print 2 times ('I' then 'need") and so on and so
* forth.
*/
System.out.print(broken[i] + " ");
}
System.out.println(); // Since the above method is a print this puts an '\n' (enter) moving the next prints on the next line
n++; //Makes 'n' go up so that it is larger for the next go around
if (n == broken.length) { //the '.length' portion says how many indexes there are in the array broken
/* If you don't have this then the 'while' will go on forever. basically when 'n' hits
* the same number as the amount of words in the array it stops printing.
*/
done = true;
}
}
}

Categories

Resources