Substituting a character with a string from a string array in java - java

Hello to all coders out there, any help is appreciated for this is a personal project and not for a school that I thought would be fun, but not turning out to be so. Now the project is to read in an input file, the compare it to a srting[] alphabets = {"a","b","c"...."z"} then to replace the alphabets with another string[] newAlphabets = {"Apple", "Ball", "Cat", .... "Zebra"}. Now I have tried the simple replaceAll() example and it kinda worked. But the plan is to input a .txt file and have the substitution run and output with a new file.
JamesBond.txt: Name is Bond, James Bond.
Output.txt should be: NoAppleMonkeyElephant InsectSnake BallOpenNoDuck, JungelAppleMonkeyElephantSnake BallOpenNoDuck.
Here's what I have so far:
import java.io.IOException;
import java.io.File;
import java.util.Scanner;
public class FnR {
// array of alphabets
static String[] alphabet = {"a","b","c","d","e","f","g","h","i",
"j","k","l","m","n","o","p","q","r","s","t","u",
"v","w","x","y","z"};
// replace the alphabets with substituted string
static String[] newAlphabets =
{"Apple","Bat","Cat","Dog","Egale","Fox","Goat","Horse","Insect","Jungle",
"King","Lion","Monkey","Nose","Open","Push","Quit","Run","Stop","Turn",
"Up","Volume","Water","X-mas","Yes","Zip"};
#SuppressWarnings("resource")
public static void main(String[] arg) throws IOException{
try {
//reads in the file
Scanner input = new Scanner("JamesBond.txt");
File file = new File(input.nextLine());
input = new Scanner(file);
while (input.hasNextLine()) {
String line = input.nextLine();
//prints the txt file out
System.out.println(line);
// replaces the letter j with Jungel in the text regardless of
case
String newtxt1 = line.replaceAll("J","Jungle");
//prints new text
System.out.println(newtxt1);
}
input.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} }
Output:
Name is Bond, James Bond
Name is Bond, Jungleames Bond

Not going to give you the code. This answer is providing hints for you to write the code yourself.
Don't use replaceAll(). You'd have to do it 26 times, and that is not really a good solution.
Instead, create a StringBuilder for building up the result string. Then loop through the characters of the input string with a normal for loop using String methods length() and charAt().
Now here is the main "trick" that will simplify your code. Java stores text in Unicode, where letters a to z are stored consecutively. That means you can calculate the index into your newAlphabets array. To do that, you'll write code like this:
char ch = ...;
if (ch >= 'a' && ch <= 'z') {
int idx = ch - 'a'; // number between 0 and 25, inclusive
// use idx here
} else if (ch >= 'A' && ch <= 'Z') {
int idx = ch - 'A'; // number between 0 and 25, inclusive
// use idx here
} else {
// not a letter
}
Hope this helps you write the code yourself.

Related

How can I read a string from scanner, and convert each letter to a different value?

I am working on taking a string that has been imported as a file, taking each character, and "encrypting" it by changing it to the next letter. Basically, a is b, b is c, c is d, and etc. It isn't secure but it isn't meant to be for these purposes. The scanned string can be anything but I'm using "Orange juice is great! I drank 83,214 cups of it yesterday." It is in a file called input.txt.
My code is as follows:
import java.util.Scanner;
import java.io.*;
public class ReadFileExample{
public static void main(String[] args){
//String fileName = "input.txt";
//File file = new File(fileName);
//Scanner in = new Scanner(file);
try{
Scanner in = new Scanner(new File("input.txt"));
while(in.hasNext() == true){
String input = in.next();
System.out.println(input);
}
}
in.close();
}
catch(FileNotFoundException exception){
System.out.println("Could not find the file.");
}
}
}
I thought about converting the string to an array but I'm not sure how to go about that. Maybe like this?
char[] charArray = input.toCharArray();
for (char c : charArray){
System.out.println(c);
}
I'm really not sure where to go with this. I also wondered about for(i = 0; i < string.length; i++) Not sure how to go about that either. Once it is done, I need to print it out. Then, I need to take that same string, encrypt it again.
The second file encryption technique is to replace each letter with the place it is in the alphabet. We will use two digits for every letter. For example, the letter ‘a’ is 01, the letter ‘b’ is 02, the letter ‘c’ is 03, the letter ‘z’ is 26. So that we can use capital letters we start ‘A’ with 27, ‘B’ with 28, ‘C’ with 29, and so on.
For numbers, we convert each digit into two letters: the first two letters that they stand for. The first letter is capitalized followed by a lower-case letter. For example, 8 written out is eight. So, 8 would be encrypted to “Ei”, 1 would be encrypted to “On”, 2 would be encrypted to “Tw”, 3 would be “Th” and so on.
Note that “10” is actually two digits, so it would be encrypted as “1” and “0”: “OnZe”
If you come to a non-letter character (spaces, punctuation, numbers, etc.), just print them as is without encrypting.
Any help is appreciated even if it is suggesting what to search for to answer my questions.
Here is the below code, the code is explained in the comments, if you need more help then comment below, the demo can be found at the below link!
I have given the demo for the static string that you have given the example for.
Demo
import java.util.HashMap;
/**
*
* #author Sai-Karan
*/
public class App {
//Function to return the substring for the second encoding method
//Example 1 will return On, and 2 will return Tw ....etc
public static String findstringmap(char c)
{
//Create a hashmap and add the key elements and the string definitions
HashMap <Integer, String> hmap = new HashMap <Integer, String>();
/*Adding elements to HashMap*/
hmap.put(1, "One");
hmap.put(2, "Two");
hmap.put(3, "Three");
hmap.put(4, "Four");
hmap.put(5, "Five");
hmap.put(6, "Six");
hmap.put(7, "Seven");
hmap.put(8, "Eight");
hmap.put(9, "Nine");
hmap.put(0, "Zero");
/* Get values based on key*/
int num_value = Character.getNumericValue(c);
//convert to the numeric value
String var = hmap.get(num_value);
//get the substring
String ret_str = var.substring(0, 2);
return ret_str;
}
public static void main(String[] args) {
// TODO code application logic here
String l1 = "Orange juice is great! I drank 83,214 cups of it yesterday.";
//String final contains the result
String Final = "";
String next = "";
for(int i =0 ; i< l1.length(); i++)
{
//char c = l1.charAt(i);
if (l1.charAt(i) == ' ')
{
next = " ";
}
else if (l1.charAt(i) == '!')
{
next = "!";
}
else if(l1.charAt(i) == ',')
{
next = ",";
}
else if(l1.charAt(i) == '.')
{
next = ".";
}
else if(!(Character.isDigit(l1.charAt(i))))
{
int val = l1.charAt(i);
next = String.valueOf( (char) (val + 1));
// System.out.println(next);
}
else if(Character.isDigit(l1.charAt(i)))
{
next = findstringmap(l1.charAt(i));
}
Final = Final + next;
}
System.out.println(Final);
}
}

Replace characters from a string with it's position

I am having difficulty in the following, replacing certain characters from the string
There will be two inputs, first will be character and second will be string
then I need to replace all those characters from the string with it's position
for example ,
the input and output of my program are as follows which is absolutely correct as per the requirement
Input : i this is Ignite
( Here "i" is the first input and "this is Ignite" is the second input
Output : th2s 5s 8gn11te
Input : i this is ignite and i am pratik
Output : th2s 5s 8gn11te and 20 am prat30k
The replacement should not be case-sensitive.
I had written the following program but it's having some bugs, Bugs in the sense that I am actually doing some project online and the automated sytem is not accepting the program because of some logical error.The automated system does some test cases with different inputs and check the output ( not exceptions or invalid inputs) can someone help me identify it ?
import java.util.*;
import java.io.*;
class rplc
{
public static void main(String args[])
{
String str,temp="";
char ch, ch2;
int arr[]=new int[100];
int len,i,x=0;
Scanner input=new Scanner(System.in);
ch=input.next().charAt(0);
str=input.nextLine();
str=str.replaceAll("^\\s+","");
ch2=ch;
if(Character.isUpperCase(ch))
ch2=Character.toLowerCase(ch);
else if(Character.isLowerCase(ch))
ch2=Character.toUpperCase(ch);
len=str.length();
temp=str;
for(i=0;i<len;i++)
{
if(str.charAt(i)==(int)ch || str.charAt(i)==(int)ch2)
{
arr[x]=i;
x=x+1;
}
}
x=0;
for(i=0;i<len;i++)
{
if(str.charAt(i)==(int)ch || str.charAt(i)==(int)ch2)
{
temp=str.substring(0,i);
temp=temp+(arr[x]);
temp=temp+str.substring(i+1,len);
str=temp;
len=temp.length();
x=x+1;
}
}
System.out.print(temp);
}
}
Seems like your code should work. Just in case I tried writing a simpler program:
Scanner input=new Scanner(System.in);
char ch = Character.toLowerCase(input.next().charAt(0));
String str = input.nextLine().trim().toLowerCase();
input.close();
StringBuffer buf = new StringBuffer();
for (int i = 0; i < str .length(); i++) {
if (str.charAt(i) == ch) {
buf.append(i);
}
else {
buf.append(str.charAt(i));
}
}
System.out.println(buf.toString());
And the output seems to be same.
Perhaps your function should return the value instead of printing it?
From the comments I understand that there will be only 1 input from the user.
The following input:
i this is ignite and i am pratik
Where the first 'i' is the charcter which needs to be replaced in 'this is ignite and i am pratik'.
Modify following:
str=input.nextLine();
str=str.replaceAll("^\\s+","");
to
str = input.nextLine();
str = str.substring(1);
str = str.replaceAll("^\\s+", "");
Try Something like this,
Scanner s = new Scanner(System.in);
String Line = s.nextLine();
String ch = Line.substring(0,Line.indexOf(" ")).trim();
Line = Line.substring(Line.indexOf(" ")).trim();
String[] x= Line.split(ch);
String y="";
for(String t:x){
y=y.equals("")?t:y+y.length()+t;
}
System.out.println(y);
I did some code cleaning but the most important steps were to use a list of dynamic size instead of a fixed size array and a while-loop with dynamic termination instead of a for-loop. This is because the length of the output String will change (increase) when there a characters to be replaced at positions >9 and thus in your code the execution can stop in the middle of the result string and there are characters not being replaced.
There is even a special case, when the replaced character is a number itself. To avoid problems there I added this line
i = i + Integer.toString(list.get(pos)).length()-1;
in order to step over newly added number characters in the output String.
import java.util.*;
import java.io.*;
class rplc
{
public static void main(String args[])
{
List<Integer> list = new ArrayList<Integer>();
Scanner input=new Scanner(System.in);
char ch = input.next().charAt(0);
String str=input.nextLine().trim();
int len=str.length();
for(int i=0;i<len;i++)
{
if(str.charAt(i)==Character.toLowerCase(ch) || str.charAt(i)==Character.toUpperCase(ch))
{
list.add(i);
}
}
int pos = 0;
int i = 0;
while(i<str.length())
{
if(str.charAt(i)==Character.toLowerCase(ch) || str.charAt(i)==Character.toUpperCase(ch))
{
String start = str.substring(0,i)+Integer.toString(list.get(pos));
String end = i<=str.length() ? str.substring(i+1) : "";
i = i + Integer.toString(list.get(pos)).length()-1;
pos++;
str = start.concat(end);
}
i++;
}
System.out.print(str);
}
}
I can't see any special bugs. Could be that I lost sight of something. This is my first answer here and English is not my mother tongue, so please excuse any formal errors.
I liked the problem so I made my own answer. apologies for the dirty looking code. :)
Scanner input=new Scanner(System.in);
String firstInput=input.nextLine().charAt(0) + "";
//ensure its lower case
firstInput=firstInput.toLowerCase();
String secondInput=input.nextLine();
//ensure char in secondInput is lower cased too.
secondInput=secondInput.replaceAll(firstInput.toUpperCase(),firstInput);
String[] splitted=secondInput.split(firstInput);
String output="";
int current=0;
for(int i=0;i<splitted.length;i++){
String s=splitted[i];
current=current+ s.length();
if(i==splitted.length-1){
output=output+s;
}else{
output=output+s;
output=output+ current;
current++;
}
}
//edited part, as split doesn't split if firstinput is the last character of the string
if(secondInput.endsWith(firstInput)){
output=output+secondInput.length();
}
System.out.println(output);

Need to use Scanner to read a file but don't know how to compare

I am trying to write a method that reads a text file using Scanner then compare them to see if they are characters ('a' - 'z') however binary operators can't be used (compilation error). Any ideas how to work around it?
I need to convert uppercase letters to lowercase, and I have a counter that keep track of how many times each letter appeared in the text file.
I also need to ignore any symbols and numbers in the text file.
After reading your comments, I changed my code into:
import java.util.Scanner;
public class LetterInventory {
int counter = 0;
private int[] inventory;
char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
public LetterInventory () {
inventory = new int[26];
}
public void countOccurrences(Scanner file) {
while (file.hasNextLine()) {
// Read line by line and make it lowercase
String line = file.nextLine().toLowerCase();
// get all the character of the line
for (char c :line.toCharArray()) {
if (c >= 'a' && c <= 'z'){ // Check for character only
counter++;
}
}
}
}
public void displayTable () {
for (int i = 0; i < alphabet.length; i++) {
System.out.println(alphabet[i] + ": " + inventory[i]);
}
}
public void resetInventory () {
counter = 0;
}
I am still not really sure how to make this thing work.
This program is supposed to be able to read a text file, make a count each alphabet was read, ignore any symbol/number, and output a table with each letter followed by how many times they are in the text file.
As pointed out in the comments there are some problems with your code.
First: Every time you call file.next() it will try to read the next character. So what you do in your loop is: read all characters, convert to lower case but ignore this new value and carry on.
The compilation problem is due to the fact that you try to compare a string with a character.
What you want to do is something like this:
while(file.hasNext())
{
String currentTokes = file.next().toLowerCase(); //save the current token as lower text in the variable
//check each character of the string
for(char c : currentToken.toCharArray())
{
if(c <= ....) //check etc.
}
}
Another way would be to use regular expressions.
Instead of comparing file.next() to a char why not just use a regular expression?
For example:
if(file.next().matches("[a-z]")){
//do something
}
will return true if the next value picked up by the next method is a lower case character between a and z. This way you don't have to deal with unnecessary logic or worry about whether you are comparing a String to a char.
note:
I am not sure what your input is however and the above regex will only match if it is a single lower case letter not if it is a word. That said if you are reading in words you will need to split them into a character array before using the above solution.
For an example, you could try something like this:
while (file.hasNext()) {
// grabs next word/string from file
String str = file.next().toLowerCase();
// converts that string to a character array
char[] charArray = str.toCharArray();
for (char chars : charArray) {
// converts current character into a string and checks whether
// it
// is a lower case letter
if (String.valueOf(chars).matches("[a-z]")) {
// do something
}
}
}
this will work
public void countOccurrences(Scanner file) {
int[] alpha = new int[25];
while (file.hasNext()) {
char[] stringTokens = file.next().toLowerCase().toCharArray();
for (char c : stringTokens) {
if (c - 'a' > -1 || c - 'a' < 26) {
alpha[c - 'a']++;
}
}
}
}
Read inline comments for more info.
while (file.hasNextLine()) {
// Read line by line and make it lowercase
String line = file.nextLine().toLowerCase();
// get all the character of the line
for (char c : line.toCharArray()) {
if (c >= 'a' && c <= 'z'){ // check for character only
inventory[c - 'a']++; // Increment the occurrence of the Character
}
}
}

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

Count letters in a string Java

I'm doing an assignment where I'll have to code a program to read in a string from user and print out the letters in the string with number of occurrences. E.g. "Hello world" in which it should print out "h=1 e=1 l=3 o=2 ... etc.", but mine only write "hello world" and the amount of letters in total. I can't use the hashmap function, only arrays. Can someone give me a hint or two on how to proceed from the written code below to get my preferred function? I don't understand exactly how to save the written input in array.
Here's my code so far.
public class CountLetters {
public static void main( String[] args ) {
String input = JOptionPane.showInputDialog("Write a sentence." );
int amount = 0;
String output = "Amount of letters:\n";
for ( int i = 0; i < input.length(); i++ ) {
char letter = input.charAt(i);
amount++;
output = input;
}
output += "\n" + amount;
JOptionPane.showMessageDialog( null, output,
"Letters", JOptionPane.PLAIN_MESSAGE );
}
}
You don't need 26 switch cases. Just use simple code to count letter:
String input = userInput.toLowerCase();// Make your input toLowerCase.
int[] alphabetArray = new int[26];
for ( int i = 0; i < input.length(); i++ ) {
char ch= input.charAt(i);
int value = (int) ch;
if (value >= 97 && value <= 122){
alphabetArray[ch-'a']++;
}
}
After done count operation, than show your result as:
for (int i = 0; i < alphabetArray.length; i++) {
if(alphabetArray[i]>0){
char ch = (char) (i+97);
System.out.println(ch +" : "+alphabetArray[i]); //Show the result.
}
}
Create an integer array of length 26.
Iterate each character of the string, incrementing the value stored in the array associated with each character.
The index in the array for each character is calculated by x - 'a' for lower case characters and x - 'A' for upper case characters, where x is the particular character.
You can create an Array which first element will represent 'a', second 'b', etc. If you need distinction between lower and upper cases than you can add it at the end. This array will have all values equals 0 at the beginning.
Then you iterate through your sentence and you increment required values on the array.
At the end you print all values that are > 0. Simple?
Let me know if you need more help
No you should not create an array of 26. This will break if the string contains unexpected characters. (ä, ö, ü anyone?)
As I pointed out im my comment use a Map. This will work forr all posible characters out there.
import java.io.*;
public class CharCount {
public static void main(String[] args) throws IOException
{
int i,j=0,repeat=0;
String output="",input;
char c=' ';
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter name ");
input=br.readLine();
System.out.println("entered String ->\""+input+"\"");
input=input.toLowerCase();
for(i=0;i<input.length();i++)
{
for(j=0;j<output.length();j++)
{
if(input.charAt(i)==output.charAt(j) || input.charAt(i)==c)
{
repeat=1;
break;
}
}
if(repeat!=1)
{
output=output+input.charAt(i);
}
repeat=0;
}
System.out.println("non-reepeated chars in name ->\""+output+"\"");
int count[]=new int[output.length()];
for(i=0;i<output.length();i++)
{
for(j=0;j<input.length();j++)
{
if(output.charAt(i)==input.charAt(j))
count[i]=count[i]+1;
}
}
for(i=0;i<output.length();i++)
System.out.println(output.charAt(i)+"- "+count[i]);
}
}

Categories

Resources