Can't seem to clone char in a string - java

I have this assignment in school to check input string (through BufferedReader), if that string contains any vowels (like, in my language, a, ā, e, ē etc) and if they are there, you have to put character 'p' after that vowel and even after that 'p' char you have to put that vowel, after which that 'p' was inserted.
Sounds like this: dog => dopog; snails => snapaipils and so on.
The thing is - I made it working so that this char 'p' is in the right spot, but I can't put that vowel after char 'p'. For now I am getting like, dog => dopg.
In my code here:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Ld2151rdb255 {
static char[] patskani = { 'a', 'ā', 'e', 'ē', 'i', 'ī', 'u', 'ū', 'o' };
static char character;
static StringBuilder input;
public static void main(String[] args) {
char charAtPosition;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String valueEntered = br.readLine();
valueEntered = valueEntered.toLowerCase();
input = new StringBuilder(valueEntered);
// should use "String.contain"
for (int i = 0; i < input.length(); i++) {
for (int j = 0; j < patskani.length; j++) {
charAtPosition = input.charAt(i);
if (charAtPosition == patskani[j]) {
input.insert(i + 1, 'p');
// input.insert(i + 2, charAtPosition);
}
}
}
} catch (IOException e) {
System.out.println("input-output error");
}
// Rezultātu izvade
String result = input.toString();
System.out.println(result);
}
}
I tried to put input.insert(i + 2, charAtPosition);, but yea - it smells like IndexOutOfBoundary exception. It really is, no matter, how I changed the index and what method I approached to do the task.
Don't worry much about object 'patskani'. Just a 'vowels' in my language.
Any help would be appreciated, because I am kinda stuck there and don't know if there's a way of doing it just by continuing or I have to rewrite the logic.
Thanks in advance!

I would suggest that you build the output step by step, that will be easier.
So get the char, add it to the output, check if it's a patskani and if so append a p:
input = new StringBuilder(); // should be named output most likely
for (int i = 0; i < valueEntered.length(); i++) {
// get the i-th char
charAtPosition = valueEntered.charAt(i);
// append this char to "output"
input.append(charAtPosition);
// check if the char is in "patskani"
for (int j = 0; j < patskani.length; j++) {
if (charAtPosition == patskani[j]) {
// if so, append a "p" and no need to continue checking
input.append('p');
break;
}
}
}
Something like that (demo here). As a side note, note that there is something called enhanced for loop that can be handy.

Related

Replace vowel with next does not work

I have a string input and want to replace every vowel in that string with its next vowel.
However, it does not seem to work correct. I have tried various input like:
venky -> vinky // Correct
ui -> uo // Incorrect, expected ao
ai -> ao // Incorrect, expected eo
The vowel order is
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
My code is:
package test;
import java.util.Scanner;
public class Problem1 {
public static void main(String args[]) {
Scanner r = new Scanner(System.in);
String str, res;
char ch;
int i, j;
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
System.out.println("Enter a string");
str = r.nextLine();
res = str;
for (i = 0; i < str.length(); i++) {
ch = str.charAt(i);
for (j = 0; j < 4; j++) {
if (ch == 'u') {
res = str.replace(ch, 'a');
break;
} else if (ch == vowels[j]) {
res = str.replace(ch, vowels[j+1]);
break;
}
}
}
System.out.println("String after replacing the vowels with next vowel : "
+ res);
}
}
Your problem is here:
res = str.replace(ch, vowels[j+1]);
Consider the input ai. The 1st time you pass here you change the value of res to ei, the second time you replace the i in the initial string ai, not in the modified one. So res gets the new value ao.
Anyway, even if you fix this particular case you may hit some other issue with longs words containing many wovels as you replace the first occurence (imagine the case of ae you would get ie). You should build the result one char at a time, with either the unmodified letter or the next wovel.
You are replacing the vowel in your str variable and saving it to res then you break and continue on your str which has the previous vowel not replaced.
You would need put your response together char by char
Your problem is String.replace will replace all occurrence of a char in your String.
Since you traverse over your String, one original character might be replaced multiple times, for example:
acac -> ecec -> ecic
You will receive ecic instead of ecec.
So I think you can create another String based on the current Strin to avoid the sideeffect of String.replace:
char[] output = new char[str.length()];
for(i = 0; i < str.length(); i++) {
ch = str.charAt(i);
for (j = 0; j < 4; j++) {
if (ch == 'u') {
output[i] = 'a';
} else if(ch == vowels[j]) {
output[i] = vowels[j+1];
} else {
output[i] = ch;
}
}
}
String res = new String(output);
res = str.replace(ch, vowels[j+1]);
will replace the string value and put in res variable but on the next time it will not use the old res variable for further modification thats why it is giving wrong answer try changing.
str = str.replace(ch, 'a');
str = str.replace(ch, vowels[j+1]);
and print str instead of len

Kattis - Secret Chamber

I'm required to solve the following problem for one of my classes: https://open.kattis.com/problems/secretchamber
My solution seems to work, but it's failing the third test case. I implemented every rule given by the problem description, and it solves the two sample test cases no problem. I'm at my wit's end, and I don't know what I'm doing wrong.
I'm not asking for anyone to do my homework by any means whatsoever, but any pointers on what I'm missing would be greatly appreciated.
import java.io.*;
import java.util.*;
class secretchamber
{
public static void main(String[] args)
{
Scanner stdin = new Scanner(System.in);
int numTranslations = stdin.nextInt();
int numPairs = stdin.nextInt();
stdin.nextLine();
ArrayList<Character> trans1 = new ArrayList<Character>(numTranslations);
ArrayList<Character> trans2 = new ArrayList<Character>(numTranslations);
for(int i = 0; i < numTranslations; i++)
{
String temp = stdin.nextLine();
trans1.add(temp.charAt(0));
trans2.add(temp.charAt(2));
}
for(int i = 0; i < numPairs; i++)
{
String temp = stdin.nextLine();
String[] pair = temp.split("\\s+");
char[] a = pair[0].toCharArray();
char[] b = pair[1].toCharArray();
if(translates(a, b, numTranslations, trans1, trans2))
{
System.out.println("yes");
}
else
{
System.out.println("no");
}
}
}
public static boolean translates(char[] a, char[] b, int numTranslations, ArrayList trans1, ArrayList trans2)
{
//false if strings are unequal in length
if(a.length != b.length)
{
return false;
}
//true if strings are the same
else if(a == b)
{
return true;
}
else
{
for(int i = 0; i < a.length; i++)
{
//if current characters are the same, continue
if(a[i] == b[i])
{
continue;
}
//if current index of a directly translates to index of b
else if(trans1.indexOf(a[i]) == trans2.indexOf(b[i]))
{
continue;
}
//if one or both of the characters do not exist within the list of translations
else if(!(trans1.contains(a[i]) && trans2.contains(b[i])))
{
return false;
}
else
{
continue;
}
}
}
return true;
}
}
Your understanding for the problem is worng. You need to read again this part in the problem.
Two words match if they have the same length and if each letter of the first word can be turned into the corresponding letter of the
second word by using the available translations zero or more times.
This input can make your output goes worng.
Input
2 1
a c
d b
aaa abc
Expected output
no
Your output
yes
Below is solution sketch for this problem.
I got it from icpc website.
It's happenstance that your code works on the sample cases. Check the it -> of translation in the provided example carefully. i doesn't directly translate to o, but it does directy translate to r, and r translates to o. You need to follow all translation paths step by step for each character and build a graph that lets you efficiently test whether a translation is possible.
Consider buiding a structure like HashMap<Character, Set<Character>> that maps each of the 26 letters to all of the possible characters it can translate to. For the provided example, o would map to {'r', 'o', 't', 'c', 'f', 'e'}. Repeat the same procedure for each of the provided translations.
Once you've built this data structure, it's a straightforward task of iterating over characters and performing lookups. a should have the same length as b and b[i] should be in the translation set for a[i], for all i.

Java - reading values Chars in one array list and converting them into strings in another

I'm working on a program that converts a users input into Morse code.
To do this I have two text files, one storing the Morse alphabet and another storing the English alphabet.
I'm trying to read the the chars in the users input, one by one, and compare them to the chars in a character arraylist to find the appropriate index. I then just append the translation variable with the value at that index in the Morse array list. (They are organized so that this works).
Yet for some reason, I am recieveing an IndexOutOfBoundsException when it compares the char to the normals arraylist.
Here's my code:
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
public class MorseCode
{
public static String translate(String input) throws IOException
{
//Convert input to lowercase
input.toLowerCase();
//Create final statement
String translation = "";
//Store values
ArrayList<String> morse = new ArrayList<String>();
ArrayList<Character> normals = new ArrayList<Character>();
//Scan and read file
Scanner morseFile = new Scanner(new File("morsecode.txt"));
Scanner normalsFile = new Scanner(new File("normals.txt"));
while (morseFile.hasNext())
{
morse.add(morseFile.next());
}
while (normalsFile.hasNext())
{
normals.add(normalsFile.next().charAt(0));
}
//Begin checking for chars and converting
for (int i = 0; i < input.length() + 1; i++)
{
//Set current char
char currentChar = input.charAt(i);
//Begin comparing chars
for (int b = 0; b <= normals.size() + 1; b++)
{
//If char equals x
if (currentChar == normals.get(b))
{
//Append translation
translation += morse.get(b);
}
else
{
//Nothing
}
}
}
return translation;
}
}
Remove + 1 in the condition , b <= normals.size() + 1, inside inner for loop. b <= normals.size() is enough

Compare a char to an array of chars?

package loopPractice;
import java.util.Scanner;
public class replaceVowels {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("Enter a string: ");
String s = sc.nextLine();
String originalString = s;
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c.equals(vowels[i])){
String front = s.substring(0, i);
String back = s.substring(i + 1);
s = front + "" + back;
}
}
System.out.println(originalString);
System.out.println(s);
}
}
The job is to replace all vowels in a word, How can i replace every vowel using an array of vowels?
The question is: Write a method that returns a String that is a copy of a String parameter, but without any vowels
Well, in the spirit of your question, you could write a new function that checks if an array contains a character:
public static void main(String[] args) {
System.out.print("Enter a string: ");
String s = sc.nextLine();
String originalString = s;
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (contains(c, vowels)) {
String front = s.substring(0, i);
String back = s.substring(i + 1);
s = front + "" + back;
}
}
System.out.println(originalString);
System.out.println(s);
}
private static boolean contains(char c, char[] arr) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == c) {
return true;
}
}
return false;
}
There are three big problems with this code.
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c.equals(vowels[i])){
String front = s.substring(0, i);
String back = s.substring(i + 1);
s = front + "" + back;
}
}
First, you can't use equals on a char, since char is a primitive type. Use ==.
Second, you're not checking for vowels properly. The above code compares the 0'th character of 's' to the 0'th character in the vowels array; that is, it compares it to 'a' but not to any other vowel. Similarly, it compares the character at index 1 to 'e', but not any other vowel, the character as 2 to 'i', etc.; when you get up to index 5, the program will throw an exception because vowels isn't that big.
The solution is that you need a double loop (or nested loop). For each character in s, you will need to check it against every character in the vowels array (or at least until you hit a match). So you'll need something like
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
boolean isAVowel = false;
for (int j = 0; j < vowels.length; j++) {
if (c == vowels[j]) {
isAVowel = true;
break; // will leave the inner loop but not the outer loop
}
// I'll let you finish the rest
As #cptcactus demonstrated in his answer, moving the inner loop to a new method is a good way to implement this kind of solution.
The third problem is more subtle. When you're looping through indexes in an array or string, and the loop removes elements from the array or string, you have to be very careful because the indexes will shift. Suppose your code did approximately this:
for (int i = 0; i < s.length(); i++) {
if [[[ s.charAt(i) is a vowel ]]] {
[[[ remove the i'th character from s; ]]]
}
}
Say s is "air". First i is set to 0, and s.charAt(i) is 'a'. This is a vowel, so we remove it. This means s is now "ir". Then we loop back and set i to 1. Now s.charAt(i) is 'r' since it uses the new value of s, and it never looks at the vowel 'i'.
A couple ways to work around that problem are:
make sure i is not incremented if you remove a character from it (you could use i-- which will cancel out the i++);
go backwards through the indexes (i.e. start with s.length()-1 and decrement) instead of forwards.
(There are other ways to solve this, by using the replaceAll method or a Set<Character>, but I'm assuming that this is a class and your purpose is to learn the basics of loops and such.)
String.replaceAll("[aeiou](?!\\b)", "");
Reads: Match all vowels ([aeiou]) that are not followed ((?!...)) by an "end of word" (\b). For more information read the Javadoc on java.util.regex.Pattern;
even simpler would be this (equivalent but simpler) regex:
String.replaceAll("[aeiou]\\B", "");

String index out of range, string input from File

Okay SO. I've got a try-catch block that has no issues but the thing is when I import the first line of a text file, it says that the String index is out of range:33.
That line is "The Dentist Pulled My Tooth Out"
What I'm doing is using a for loop to evaluate every character in a line until we reach the end of said line. If the character is a vowel, then I increment a vowel integer. Otherwise, if it is a blank space, then I change the blank space to a tilde(~). What I want to know is why it says my String is out of range and how would I change a blank space in the line of text from the file to a tilde. I can figure out outputting it to a different file(that's what I have to do) by myself. I'm just confused why its saying its out of range. I've pasted my entire program below.
The goal of the program is to evaluate a text file, character by character, and count the number of vowels. Also, I have to change any blank spaces to tildes, then reoutput to a different text file.
The code is below:
import java.io.File;
import java.util.Scanner;
import java.io.IOException;
import java.io.FileWriter;
public class Vowels {
public static void main(String[] args) {
Scanner inFile;
File dentist = new File("poetry.txt");
int vowels = 0;
try {
for (int i = 0; i >= 0; i++) {
inFile = new Scanner(new File("poetry.txt"));
String str1 = inFile.nextLine();
for (int a = 0; a >= 0; a++) {
String start;
start = str1.substring(a, a + 1);
if (start.equalsIgnoreCase("a") == true)
vowels++;
else if (start.equalsIgnoreCase("e") == true)
vowels++;
else if (start.equalsIgnoreCase("i") == true)
vowels++;
else if (start.equalsIgnoreCase("o") == true)
vowels++;
else if (start.equalsIgnoreCase("u") == true)
vowels++;
else if (start.equalsIgnoreCase(" "))
start = " ";
}
}
} catch (IOException i) {
System.out.println("Error");
}
}
}
You should take the new Scanner out of the loop, then change your loop to while(inFile.hasNextLine()) ... you're not using "i" at all.
Also, your inner loop will never end, and that's why you're getting an index exception. Instead of having a>=0, replace that with a<str1.length().
Replace that substring thing with str1.charAt(a), then compare that char (not String) to single quoted chars... 'a', 'e', 'i', etc. using a simple ==. char is a native datatype, so you can just do Character.toLowerCase(start) == 'a' Notice I forced the character to lowercase before comparing, which replaces the "ignore case". You don't have to do the Character.toLowerCase every time if you just say start = Character.toLowerCase(start) though.
There are several things going on in this piece of code.
for(int i = 0; i>=0; i++){
inFile = new Scanner(new File("poetry.txt"));
String str1 = inFile.nextLine();
That will loop almost 2^32/2 - 1 times.
That creates a new Scanner object everytime.
You are reading the first time everytime.
for(int a = 0; a >= 0; a++) {
String start;
start = str1.substring(a, a + 1);
}
This will again loop for 2^32/2 - 1 times.
Since the str1 is not as big as the variable 'a' can be, it crashes. You need to make this loop as
for(int a = 0; a < (str1.length() - 1); a++) {
String start = str1.substring(a, a + 1);
}
This should sorta fix your problem.
You can do away the long if-else structure by using
String STR_VOWELS = "aeiou";
if(STR_VOWELS.contains(start)) {
vowels++;
} else if (start.equals(" ")) {
// you can remove this else as well, as you are not doing any thing different here.
start = " ";
}
Hope this helps.
For replace blank,
When you get the input in to a one string then simply use
String my_new_str = my_str.replaceAll(" ", "~");
then write back to a file
String replace
try replacing second for loop with following code, this shall fix your problem
String str1 = inFile.nextLine();
for(int a = 0; a < str1.length()-1; a++){ // a< string.length() otherwise exception will occur

Categories

Resources