Efficiency in for loop - java

How could the following code snippet be optimized? I'm creating space objects to be filled in a 2D array to act as a chess board and am using this to create a more standard naming system.
String name = null;
for(int r = 7; r > -1; r--)
for(int c = 0; c < 8; c++)
{
if(c == 0)
name = "A";
else if(c == 1)
name = "B";
else if(c == 2)
name = "C";
else if(c == 3)
name = "D";
else if(c == 4)
name = "E";
else if(c == 5)
name = "F";
else if(c == 6)
name = "G";
else
name = "H";

final static char[] letters = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
:
for (int c=0; c<8; c++) {
name = letters[c];
:
This has name as a char - does it really need to be a String? If so, make the obvious changes. Define letters as a String[] rather than runtime conversion from char-to-String if you are concerned with efficiency.

You could iterate over characters and change it to a string like this :
for (int r=7; r >= 0; r--) {
for (char c='A'; c <= 'H'; c++) {
name = c + "";

You never finished your for loops, but here is one way to optimize what you have showed us so far:
String name = null;
String letters = "ABCDEFGH";
for (int r=7; r >= 0; r--) {
for (int c=0; c < 8; c++) {
name = letters.charAt(c) + "";
// the rest of your logic
}
}

The ASCII code for 'A' is 65 and for 'H' is 72. Then, you can do something like this
for (int r = 7; r > -1; r--) {
for(int c = 65; c < 73; c++) {
name = Character.toString((char) c);
//or
name = "" + (char) c;
}
}

Related

How to get indexes of char in the string

I want to find vowels positions in the string. How can I make shorter this code?
I tried contains and indexOf method but couldn't do it.
String inputStr = "Merhaba";
ArrayList<Character> vowelsBin = new ArrayList<Character>(Arrays.asList('a', 'e', 'i', 'o', 'u'));
ArrayList<Integer> vowelsPos = new ArrayList<Integer>();
for (int inputPos = 0; inputPos < inputStr.length(); inputPos = inputPos + 1)
for (int vowelPos = 0; vowelPos < vowelsBin.size(); vowelPos = vowelPos + 1)
if (inputStr.charAt(inputPos) == vowelsBin.get(vowelPos)) vowelsPos.add(inputPos);
return vowelsPos;
I assume you want to get m2rh5b7 from your input string Merhaba based on your code, then the below works fine,
String input = "Merhaba";
StringBuilder output = new StringBuilder();
for(int i = 0; i < input.length(); i++){
char c = input.toLowerCase().charAt(i);
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'){
output.append(i+1);
} else {
output.append(c);
}
}
System.out.println(output); // prints --> m2rh5b7
Or if you want just position of the vowels position only, the below is fine,
String input = "Merhaba";
for(int i = 0; i < input.length(); i++){
char c = input.toLowerCase().charAt(i);
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'){
System.out.println(i);
}
}
you can use regex also, please refer the above from Alias.

I get java.lang.StringIndexOutOfBoundsException when translating c++ code into java code

I'm trying to solve this problem
https://vjudge.net/problem/UVALive-6805
I found solution but in c++ , Can anybody help me converting it to java code. I'm very newbie to programming
I tried a lot of solutions but non of them work.
Please I need help in this if possible
I don't know for example what is the equivalent for .erase function in c++ in java
Also is is sbstr in c++ provide different result from java ?
#include <iostream>
#include <string>
using namespace std;
int syllable(string word)
{
int L = word.size();
int syllable;
if (L>=7)
{
syllable = 3;
}
else if (L==6)
{
int indicator = 0;
for (int k=0; k<=L-2; k++)
{
string subword = word.substr(k, 2);
if (subword == "ng" || subword == "ny")
{
indicator++;
}
}
if (indicator == 0)
{
syllable = 3;
}
else
{
syllable = 2;
}
}
else if (L == 4 || L == 5)
{
syllable = 2;
}
else if (L == 3)
{
char Char = word[0];
if (Char=='a' || Char=='A' || Char=='e' || Char=='E' || Char=='i' || Char=='I' || Char=='o' || Char=='O' || Char=='u' || Char=='U')
{
syllable = 2;
}
else
{
syllable = 1;
}
}
else
{
syllable = 1;
}
return syllable;
}
int main()
{
string word;
int T;
cin >> T;
for (int i=1; i<=T; i++)
{
int syl[] = {0, -1, -2, -3};
string rhy[] = {"a", "b", "c", "d"};
int verse = 0;
int stop = 0;
while (stop == 0)
{
cin >> word;
int L = word.size();
char end = word[L-1];
if (end == '.')
{
stop = 1;
}
if (word[L-1] == ',' || word[L-1] == '.')
{
word = word.erase(L-1, 1);
L = word.size();
}
if (verse<=3)
{
syl[verse] = syl[verse] + syllable(word);
}
if (end == ',' || end == '.')
{
if (verse<=3)
{
rhy[verse] = word.substr(L-2, 2);
}
verse++;
if (verse<=3)
{
syl[verse] = 0;
}
}
}
int A = 0, B = 0, C = 0, D = 0;
for (int k=0; k<4; k++)
{
if (syl[k] >= 8 && syl[k] <= 12)
{
A = A + 10;
}
}
for (int k=0; k<2; k++)
{
if (rhy[k] == rhy[k+2])
{
B = B + 20;
}
}
for (int k=0; k<2; k++)
{
if (syl[k] == syl[k+2])
{
C = C + 10;
}
}
if (verse > 4)
{
D = (verse - 4) * 10;
}
int E = A + B + C - D;
cout << "Case #" << i << ": " << A << " " << B << " " << C << " " << D << " " << E << endl;
}
}
here is my trying
import java.util.*;
public class First {
public static int syllable(String word) {
int L = word.length();
int syllable;
if (L >= 7) {
syllable = 3;
} else if (L == 6) {
int indicator = 0;
for (int k = 0; k < L - 3; k++) {
String subword = word.substring(k, 2);
if (subword == "ng" || subword == "ny") {
indicator++;
}
}
if (indicator == 0) {
syllable = 3;
} else {
syllable = 2;
}
} else if (L == 4 || L == 5) {
syllable = 2;
} else if (L == 3) {
char Char = word.charAt(0);
if (Char == 'a' || Char == 'A' || Char == 'e' || Char == 'E' || Char == 'i' || Char == 'I' || Char == 'o'
|| Char == 'O' || Char == 'u' || Char == 'U') {
syllable = 2;
} else {
syllable = 1;
}
} else {
syllable = 1;
}
return syllable;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String word;
int T;
T = sc.nextInt();
for (int i = 1; i <= T; i++) {
int syl[] = { 0, -1, -2, -3 };
String rhy[] = { "a", "b", "c", "d" };
int verse = 0;
int stop = 0;
while (stop == 0) {
word = sc.next();
int L = word.length();
char end = word.charAt(L-1);
if (end == '.') {
stop = 1;
}
if (word.charAt(L-1) == ',' || word.charAt(L-1) == '.') {
word.substring(L-1, 1);
L = word.length();
}
if (verse <= 3) {
syl[verse] = syl[verse] + syllable(word);
}
if (end == ',' || end == '.') {
if (verse <= 3) {
rhy[verse] = word.substring(L - 2, 2);
}
verse++;
if (verse <= 3) {
syl[verse] = 0;
}
}
}
int A = 0, B = 0, C = 0, D = 0;
for (int k = 0; k < 4; k++) {
if (syl[k] >= 8 && syl[k] <= 12) {
A = A + 10;
}
}
for (int k = 0; k < 2; k++) {
if (rhy[k] == rhy[k + 2]) {
B = B + 20;
}
}
for (int k = 0; k < 2; k++) {
if (syl[k] == syl[k + 2]) {
C = C + 10;
}
}
if (verse > 4) {
D = (verse - 4) * 10;
}
int E = A + B + C - D;
System.out.println("Case #" + i + ": " + A + " " + B + " " + C + " " + D + " " + E);
}
}
}
The Exception is thrown by your second and your third call of String substring method. Your beginIndex is higher than your endIndex. As you can see in here https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int,%20int) beginIndex always has to be lower than the endIndex.
Before answering your question, there are some important points to mention in regards to Strings and Java in general.
Strings are immutable (This also applies to C++). This means that no method called on a String will change it, and that all methods simply return new versions of the original String with the operations done on it
The substring method in java has two forms.
One takes in beginIndex and returns everything from beginIndex to str.length() - 1 (where str represents a String)
The other takes in the beginIndex, and the endIndex, and returns everything from beginIndex to endIndex - 1. The beginIndex should never be larger than endIndex otherwise it throws an IndexOutOfBoundsException
C++'s substring method (string::substr()) takes in the beginning "index" and takes in the number of characters after it to include in the substring. So by doing substr(L-2, 2) you get the last two characters of the string.
Java will never allow you to go out of bounds. That means you need to constantly check whether you are within the bounds of anything you are iterating through.
With all this in mind, I would go and verify that all of the substring() method calls are returning the proper range of characters, and that you are properly reassigning the values returned from substring() to the proper variable.
To mimic C++'s string::erase(), depending on what part of the word you want to erase, you want to get the substring of the part before and the substring of the part after it and add them together.
Ex. Lets say I have a String line = "I do not like the movies"; Since it is impossible for anyone to not like movies, we want to cut out the word not
We do this by doing what I said above
String before = line.substring(0, 5); // This gives us "I do " since it goes up to but not including the 5th index.
String after = line.substring(5 + 3); // This gives us the rest of the string starting after the word "not" because not is 3 characters long and this skips to the 3rd index after index 5 (or index 8)
line = before + after; // This'll add those two Strings together and give you "I do like the movies"
Hope this helps!

Having a runtime error of ArrayIndexOutOfBoundsException: 97

I am having an error, can someone please help me out. I am trying to print highest occurring vowel in the string.
void vowelCount() {
int countO = 0 ,countU = 0,countI = 0 ,countA = 0 ,countE = 0 ;
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
int[] count = new int[] {countA,countE,countI,countO ,countU};
int maxCount = 0;
char maximumChar = ' ';
for (int i = 0; i < TEXT.length(); i++) {
char ch = TEXT.charAt(i);
if (ch == vowels[0]) {
countA++;
}
if (ch == vowels[1]) {
countE++;
}
if (ch == vowels[2]) {
countI++;
}
if (ch == vowels[3]) {
countO++;
}
if (ch == vowels[4]) {
countU++;
}
}
for( int i = 0; i< vowels.length ; i++) {
if (count[vowels[i]] > maxCount) {
maxCount = count[vowels[i]];
maximumChar = vowels[i];
}
}
System.out.println();
System.out.println("The most used lowercase vowel is " + maximumChar + " for " + maxCount + " times.");
}
Arrayindexoutofbound exception results, i am not quite sure where could me my error. Tried for such a long time still the error repeats.
I'd say that count[vowels[i]] is your problem. vowels[i] will not be in the range [0..4] and hence you exceed the bounds of your array. You want count[i] instead. You could try the following simplified code
void vowelCount() {
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
int[] count = new int[vowels.length];
int maxCount = 0;
char maximumChar = ' ';
for (int i = 0; i < TEXT.length(); i++) {
char ch = TEXT.charAt(i);
for (int j=0; j<vowels.length; j++) {
if (ch == vowels[j]) {
count[j]++;
break;
}
}
}
for (int i = 0; i<vowels.length; i++) {
if (count[i] > maxCount) {
maxCount = count[i];
maximumChar = vowels[i];
}
}
System.out.println();
System.out.println("The most used lowercase vowel is " + maximumChar + " for " + maxCount + " times.");
}
The problem is here - if (count[vowels[i]] > maxCount) {
vowels[i] will give you a vowel that is a char. When used as index to fetch from char array, the character gets converted into its ASCII value, which wont be in the range of 0 to 4.
I would say, you should try to find your mistakes, rather than finding a solution. Your following code doesn't do what you expect.
for (int i = 0; i < TEXT.length(); i++) {
char ch = TEXT.charAt(i);
if (ch == vowels[0]) {
countA++;
}
if (ch == vowels[1]) {
countE++;
}
if (ch == vowels[2]) {
countI++;
}
if (ch == vowels[3]) {
countO++;
}
if (ch == vowels[4]) {
countU++;
}
}
When you are updating the variables with countX++, it isn't modifying the values stored in the count[] array, because you already initialised them with 0s i.e. the initial values of countX.
You would get an ArrayIndexOutOfBoundsException, because of these lines:
if (count[vowels[i]] > maxCount) {
maxCount = count[vowels[i]];
maximumChar = vowels[i];
}
Here the vowels[i] is having chars, when you use it as count[vowels[i]] you are using the ascii value of the char stored in the vowels array as an index to access the value in the count array.
In the exception 97 is printed as it is the ascii value of the char 'a'.
You should increment the count array data instead of the variables countO, countU, etc.. variables. You also need to iterate through the count array and find the max number from it and also assign the character from the vowel array to the maximumChar variable.
static String TEXT = "teeaaaiist";
static void vowelCount() {
int countO = 0 ,countU = 0,countI = 0 ,countA = 0 ,countE = 0 ;
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
int[] count = new int[] {countA,countE,countI,countO ,countU};
int maxCount = 0;
char maximumChar = ' ';
for (int i = 0; i < TEXT.length(); i++) {
char ch = TEXT.charAt(i);
if (ch == vowels[0]) {
count[0]++;
}
if (ch == vowels[1]) {
count[1]++;
}
if (ch == vowels[2]) {
count[2]++;
}
if (ch == vowels[3]) {
count[3]++;
}
if (ch == vowels[4]) {
count[4]++;
}
}
for( int i = 0; i< count.length ; i++) {
if (count[i] > maxCount) {
maxCount = count[i];
maximumChar = vowels[i];
}
}
System.out.println();
System.out.println("The most used lowercase vowel is " + maximumChar + " for " + maxCount + " times.");
}
public static void main(String[] args) {
vowelCount();
}

Don't know how manipulate strings

Take as input S, a string. Write a function that replaces every odd character with the character having just higher ASCII code and every even character with the character having just lower ASCII code. Print the value returned.
package assignments;
import java.util.Scanner;
public class strings_odd_even_char {
static Scanner scn = new Scanner(System.in);
public static void main(String[] args) {
String str = scn.nextLine();
for (int i = 0; i < str.length(); i = i + 2) {
char ch = str.charAt(i);
ch = (char)((ch + 1));
System.out.println(ch);
}
for (int j = 1; j < str.length(); j = j + 2) {
char ch = str.charAt(j);
ch = (char)((ch - 1));
System.out.print(ch);
}
}
}
The problem with my code is that it is first printing the values for all the odd characters and then for even characters but what I want is that they get printed in proper sequence like for input --> abcg , the output should be --> badf .
I'd hold the "incremenet" value in a variable and alternate it between +1 and -1 as I go voer the characters:
private static String change(String s) {
StringBuilder sb = new StringBuilder(s.length());
int increment = 1;
for (int i = 0; i < s.length(); ++i) {
sb.append((char)(s.charAt(i) + increment));
increment *= -1;
}
return sb.toString();
}
Just use one loop that handles both characters:
for (int i = 0; i < str.length(); i = i + 2) {
char ch = str.charAt(i);
ch = (char) (ch + 1);
System.out.print(ch);
if (i + 1 < str.length()) {
ch = str.charAt(i + 1);
ch = (char) (ch - 1);
System.out.print(ch);
}
}
You only need to iterate one time but do different operation (char+1) or (char-1) depending on the i:
public static void main(String[] args) {
String str = scn.nextLine();
for(int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i % 2 == 0) { // even
ch += 1;
} else { // odd
ch -= 1;
}
System.out.print(ch);
}
}
You are using two loops, but you only need one. You can use the % operator to tell if i is even or odd, and then either subtract or add accordingly:
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i % 2 == 0) {
ch = (char)((ch + 1));
System.out.println(ch);
} else {
ch = (char)((ch - 1));
System.out.print(ch);
}
}
You can do it in one for loop, to do that you will need to check whether the current index is even or odd. if current index is even you will increment char and print, if it is odd you will decrement char and print. to check if even or odd using % operator
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i%2 == 0) {
ch = ch + 1;
System.out.println(ch);
continue;
}
ch = ch - 1;
System.out.println(ch);
}

How to use ASCII in array

I want to write a program that takes a string text, counts the appearances of every letter in English and stores them inside an array.and print the result like this:
java test abaacc
a:***
b:*
c:**
* - As many time the letter appears.
public static void main (String[] args) {
String input = args[0];
char [] letters = input.toCharArray();
System.out.println((char)97);
String a = "a:";
for (int i=0; i<letters.length; i++) {
int temp = letters[i];
i = i+97;
if (temp == (char)i) {
temp = temp + "*";
}
i = i - 97;
}
System.out.println(temp);
}
Writing (char)97 makes the code less readable. Use 'a'.
As 3kings said in a comment, you need an array of 26 counters, one for each letter of the English alphabet.
Your code should also handle both uppercase and lowercase letters.
private static void printLetterCounts(String text) {
int[] letterCount = new int[26];
for (char c : text.toCharArray())
if (c >= 'a' && c <= 'z')
letterCount[c - 'a']++;
else if (c >= 'A' && c <= 'Z')
letterCount[c - 'A']++;
for (int i = 0; i < 26; i++)
if (letterCount[i] > 0) {
char[] stars = new char[letterCount[i]];
Arrays.fill(stars, '*');
System.out.println((char)('a' + i) + ":" + new String(stars));
}
}
Test
printLetterCounts("abaacc");
System.out.println();
printLetterCounts("This is a test of the letter counting logic");
Output
a:***
b:*
c:**
a:*
c:**
e:****
f:*
g:**
h:**
i:****
l:**
n:**
o:***
r:*
s:***
t:*******
u:*

Categories