Don't know how manipulate strings - java

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);
}

Related

How to fix: Number of occurrences of a letter in a string

I'm trying to count the number of occurrences of letters that are in string. The code that I have written technically does what I want, but not the way I want to do it. For example, if I input "Hello World", I want my code to return "a=0 b=0 c=0 d=0 e=1 etc...." with the code I have written it returns "H=1, e=1, l=2 etc...."
Also how would I make sure that it is not case sensitive and it doesn't count spaces.
Code:
import java.util.Scanner;
public class Sequence {
private static Scanner scan = null;
public static void main(String[] args) {
scan = new Scanner(System.in);
String str = null;
System.out.print("Type text: ");
str = scan.nextLine();
int[] count = new int[255];
int length = str.length();
for (int i = 0; i < length; i++)
{
count[str.charAt(i)]++;
}
char[] ch = new char[str.length()];
for (int i = 0; i < length; i++)
{
ch[i] = str.charAt(i);
int find = 0;
for (int j = 0; j <= i; j++)
{
if (str.charAt(i) == ch[j])
find++;
}
if (find == 1)
{
System.out.print(str.charAt(i) + "=" + count[str.charAt(i)] + " ");
}
}
}
}
As I hinted in my original comment you only need an array of 26 int(s) because there are only 26 letters in the alphabet. Before I share the code, it is important to note that Java char is an integral type (and, for example, 'a' + 1 == 'b'). That property is important, because it allows you to determine the correct offset in an array (especially if you force the input to lower case). Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Type text: ");
String str = scan.nextLine();
int[] count = new int[26];
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i)); // not case sensitive
if (ch >= 'a' && ch <= 'z') { // don't count "spaces" (or anything non-letter)
count[ch - 'a']++; // as 'a' + 1 == 'b', so 'b' - 'a' == 1
}
}
for (int i = 0; i < count.length; i++) {
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
}
System.out.println();
If you really want to see all of the letters that have counts of zero (seems pointless to me), change
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
to remove the if and just
System.out.printf("%c=%d ", 'a' + i, count[i]);
Change str = scan.nextLine(); to str = scan.nextLine().toLowerCase().replaceAll("\\s+","");
.toLowerCase() is a method which makes every char in the string lowercase.
.replaceAll() is a method which replaces one char with another. In this case, it replaces whitespaces with nothing.

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();
}

Longest String With Chars Palindrome

Problem description from school assignment
Longest String With Palindrome
I'm getting complexity O(N^2). How can I achieve O(N*log(N))**
My code
int maxL = 0;
for (int i = 0; i < S.length(); i++) {
String currentString = String.valueOf(S.charAt(i));
for (int j = i + 1; j < S.length(); j = j + 1) {
String jStr = String.valueOf(S.charAt(j));
if (currentString.contains(jStr)) {
currentString = currentString.replace(jStr, "");
int len = j - i + 1;
if (currentString.length() == 0 && maxL < len) {
maxL = len;
}
} else {
currentString = currentString + jStr;
}
}
}
return maxL;
This problem can be solved in O(n) time using O(n) space. The following algorithm uses a bit set to keep track of the unbalanced characters for the substrings starting at the beginning of the given string. It makes a single pass through the string and remembers the states it has already seen in a hash map. Whenever we see the same state a second time, we have found a valid password: just remove the old shorter substring from the beginning of the current substring.
private static int index(char c) {
if (c < '0') throw new IllegalArgumentException("illegal char");
if (c <= '9') return c - '0';
if (c < 'a') throw new IllegalArgumentException("illegal char");
if (c <= 'z') return c - 'a' + 10;
throw new IllegalArgumentException("illegal char");
}
private static int solution(String s) {
HashMap<BitSet, Integer> states = new HashMap<>();
int longest = 0;
BitSet state = new BitSet();
states.put((BitSet) state.clone(), 0);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
state.flip(index(c));
Integer seenAt = states.get(state);
if (seenAt != null) {
int len = i - seenAt + 1;
if (len > longest) longest = len;
} else {
states.put((BitSet) state.clone(), i + 1);
}
}
return longest;
}

multiply chars by numbers in string

I would like multiply letter by number in a String and return other String.
I don't know how to concat it when number is higher than 9 and then multiply
eg.
String ="a2b10" convert to String ="aabbbbbbbbbb"
string can have different values: "a2b15", "a16b4c1","a11b14c5"
below I made it only for one letter and one number eg. a1b8, a4b7v3
import javafx.util.converter.CharacterStringConverter;
public class Test {
public static void main(String[] args) {
String txt = "a3b2";
char ch;
for (int i = 0; i < txt.length(); i++) {
ch = txt.charAt(i);
if (((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
} else if (ch >= '0' && ch <= '9')
{
int count = Character.getNumericValue(ch);
for (int j = 0; j < count; j++) {
System.out.print(txt.charAt(i - 1));
}
} else
System.out.println("not a letter");
}
}
}
In this case it's easier to use regex and group-matching to extract the letter and the number that's following it:
public static void main(String[] args) {
String txt = "a3b10";
String patt = "([a-z])([0-9]*)"; // ([a-z]) will be the first group and ([0-9]*) will be the second
Pattern pattern = Pattern.compile(patt);
Matcher matcher = pattern.matcher(txt);
while(matcher.find()) {
String letter = matcher.group(1);
String number = matcher.group(2);
int num = Integer.valueOf(number);
while (num > 0) {
System.out.print(letter);
num--;
}
}
}
OUTPUT
aaabbbbbbbbbb
You can do it like this ...
public class Test {
public static void main(String[] args) {
String txt = "a10b10";
char ch;
char tempChar = ' ';
int temp = -1;
for (int i = 0; i < txt.length(); i++) {
ch = txt.charAt(i);
if (((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
temp = -1;
tempChar = ch;
} else if (ch >= '0' && ch <= '9') {
int count = Character.getNumericValue(ch);
if (temp != -1) {
count = ((10*temp) - temp);
}
for (int j = 0; j < count; j++) {
//System.out.print(txt.charAt(i - 1));
System.out.print(tempChar);
}
temp = count;
} else {
System.out.println("not a letter");
}
}
}
}
When you're looking for numbers and you find one, keep looking for numbers until you find a letter or the end of the string.

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