Finding the index of each character in a substring - java

I feel like my logic is decent here; I don't feel like I'm completely lost. However, I do know what exactly I'm doing wrong. I can always find the index of the start of the substring, but I can never find the full count (ex. 3,4,5,6) of the index of whatever word the user enters as the substring.
I have been struggling with this for about a week trying to figure out how to do it on my own, I can't get it right.
import java.util.Scanner;
public class midterm
{
public static void main (String[] args)
{
Scanner keyboard = new Scanner(System.in);
String simplePhrase;
String portionPhrase;
int portionIndex;
int portionCount;
int portionIndexTotal;
System.out.println("Enter a simple phrase:");
simplePhrase = keyboard.nextLine();
int phraseLength = simplePhrase.length();
System.out.println("Phrase length:" +phraseLength);
System.out.println("Enter a portion of previous phrase:");
portionPhrase = keyboard.nextLine();
String portionPhraseSub = simplePhrase.substring(portionPhrase);
portionIndex = simplePhrase.indexOf(portionPhraseSub);
for (portionIndex; portionIndex <= portionPhrase; portionIndex++)
{
System.out.println("Portion phrase index:"+portionIndex);
}
}
}

I'm still confused on what you want. There are just two simple things to know and you seem to be making this more complicated than it needs to be.
To get the index of a single character, such as "c" in the word "acorn", you would do this:
String s = "acorn";
int cIndex = s.indexOf("c");
System.out.println("The index of c is: " + cIndex);
If you want to see if the string contains a chunk, you use the exact same method. So if we are looking at the word "acorn" again and you want to see where "orn" happens, you'd do this:
String s = "acorn";
int ornIndex = s.indexOf("orn");
System.out.println("The index of orn is: " + ornIndex);
Remember that indexes start from 0 in java, so the index of "a" in "acorn" is 0, of "c" is 1, of "o" is 2, and so on.
I hope that helps. Good luck :)
EDIT: You just commented this:
"I guess, my question is one i get my code to compile, How would I go about counting every single letter of my substring?"
I'll answer that as best as I can, though again, that still is a confusing question.
What do you even mean by count" every letter? If you want to break your word into individual letters, you can do something like this:
String s = "acorn";
char[] characters = new char[s.length()-1];
for(int i = 0; i < s.length() - 1; i++) {
char[i] = s.charAt(i);
}
But I have no clue why you'd want to do that...you can always access any character in a string at a given index with STRING.charAt(index), or if you want to have a String result, STRING.substring(index, index+1)

Related

How do i print the the first initial of a string and the last word of a string?

How do I print only the first letter of the first word and the whole word of the last? for example,
I will request username input like "Enter your first and last name" and then if I type my name like "Peter Griffin", I want to print only "P and Griffin". I hope this question make sense. Please, help. I'm a complete beginner as you can tell.
Here is my code:
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("Enter your first and last name");
String fname=scan.next();
}
The String methods trim, substring, indexof, lastindexof, and maybe split should get you going.
This should do the work (typed directly here, so syntax errors might be there)
String fname=scan.nextLine(); // or however you would read whole line
String parts=fname.split(" ");
System.out.printf("%s %s",parts[0].substring(0,1),parts[parts.length-1]);
What you have to do next:
Check if there actually at least 2 elements in parts array
Check if first element is actually at least 1 char (no empty parts)
Check if there is actually line to read
Do your next homework yourself, otherwise you will not anything
I recommand you to watch subString(1, x) and indexOf(" ") to cut from index 1 to first space.
or here a other exemple, dealing with lower and multi name :
String s = "peter griffin foobar";
String[] splitted = s.toLowerCase().split(" ");
StringBuilder results = new StringBuilder();
results.append(String.valueOf(splitted[0].charAt(0)).toUpperCase() + " ");
for (int i = 1; i < splitted.length; i++) {
results.append(splitted[i].substring(0, 1).toUpperCase() + splitted[i].substring(1)+" ");
}
System.out.println(results.toString());

How can I put multiple parts of a string into a list?

So the goal is to look for patterns like "zip" and "zap" in the string, starting with 'z' and ending with 'p'. Then, for all such strings, delete the middle letter.
What I had in mind was that I use a for loop to check each letter of the string and once it reaches a 'z', it gets the indexOf('p') and puts that and everything in the middle into an ArrayList, while deleting itself from the original string so that indexOf('p') can be found.
How can I do that?
This is my code so far:
package Homework;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
public class ZipZap {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List < String > list = new ArrayList < String > ();
System.out.print("Write a sentence with no spaces:");
String sen = in .next();
int len = sen.length();
int p1 = sen.indexOf('p');
String word = null;
String idk = null;
for (int i = 0; i < len; i++) {
if (sen.charAt(i) == 'z') {
word = sen.substring(i, p1 + 1);
list.add(word);
idk = sen.replace(word, "");
i = 0;
}
}
}
}
use this , here i am using "\bz.p\b" pattern for finding any word that contains starting char with z and end with p anything can be in between
String s ="Write a sentence with no zip and zap spaces:";
s=s.replaceAll("\\bz.p\\b", "zp");
System.out.println(s);
output:
Write a sentence with no zp and zp spaces:
or it can be
s.replaceAll("z\\w+p", "zp");
here you can check you string
https://regex101.com/r/aKaNTJ/2
I think you’re saying that input zipzapityzoop, for example, should be changed to zpzpityzp with i, a and oo going into list. Please correct me if I misunderstood your intention.
You are on the way and seem to understand the basics. The issues I see are minor, but of course you want to fix them:
As #RicharsSchwartz mentions, to find all strings like zip, zap and zoop, you need to find p after every z you find. When you have found z at index i, you may use sen.indexOf('p', i + 1) to find a p after the z (the second argument causes the search to begin at that index).
Every time you have found a z, you are setting i back to 0, this starting over from the beginning of the string. No need to do that, and this way your program will never stop.
sen.substring(i, p1+1) takes out all of zip when I understood you only wanted i. You need to adjust the arguments to substring().
Your use of sen.replace(word, "") will replace all occurences of word. So once you fix your program to take out a from zap, zappa will become zpp (not zppa), and azap will be zp. There is no easy way to remove just one specific occurrence of a substring from a String. I think the solution is to use the StringBuilder class. It has a delete method that will remove the part between two specified indices, which is what you need.
Finally you are assigning the changed string to a different variable idk, but then you continue to search sen. This is like assigning zpzapityzoop, zipzpityzoop and zipzapityzp to idk in turn, but never zpzpityzp. However, if you use a StringBuilder as I just suggested, just use the same StringBuilder all the way through and you will be fine.

print even words from string input?

I am in a beginners course but am having difficulty with the approach for the following question: Write a program that asks the user to enter a line of input. The program should then display a line containing only the even numbered words.
For example, if the user entered
I had a dream that Jake ate a blue frog,
The output should be
had dream Jake a frog
I am not sure what method to use to solve this. I began with the following, but I know that will simply return the entire input:
import java.util.Scanner;
public class HW2Q1
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a sentence");
String sentence = keyboard.next();
System.out.println();
System.out.println(sentence);
}
}
I dont want to give away the answer to the question (for the test, not here), but I suggest you look into
String.Split()
From there you would need to iterate through the results and combine in another string for output. Hope that helps.
While there will be more simpler and easier way to do this, I'll use the basic structure- for loop, if block and a while loop to achieve it. I hope you will be able to crack the code. Try running it and let me know if there is an error.
String newsent;
int i;
//declare these 2 variables
sentence.trim(); //this is important as our program runs on space
for(i=0;i<sentence.length;i++) //to skip the odd words
{
if(sentence.charAt(i)=" " && sentence.charAt(i+1)!=" ") //enters when a space is encountered after every odd word
{
i++;
while(i<sentence.length && sentence.charAt(i)!=" ") //adds the even word to the string newsent letter by letter unless a space is encountered
{
newsent=newsent + sentence.charAt(i);
i++;
}
newsent=newsent+" "; //add space at the end of even word added to the newsent
}
}
System.out.println(newsent.trim());
// removes the extra space at the end and prints newsent
you should use sentence.split(regex) the regular expression is going to describe what separate your worlds , in your case it is white space (' ') so the regex is going to be like this:
regex="[ ]+";
the [ ] means that a space will separate your words the + means that it can be a single or multiple successive white space (ie one space or more)
your code might look like this
Scanner sc= new Scanner(System.in);
String line=sc.nextLine();
String[] chunks=line.split("[ ]+");
String finalresult="";
int l=chunks.length/2;
for(int i=0;i<=l;i++){
finalresult+=chunks[i*2]+" ";//means finalresult= finalresult+chunks[i*2]+" "
}
System.out.println(finalresult);
Since you said you are a beginner, I'm going to try and use simple methods.
You could use the indexOf() method to find the indices of spaces. Then, using a while loop for the length of the sentence, go through the sentence adding every even word. To determine an even word, create an integer and add 1 to it for every iteration of the while loop. Use (integer you made)%2==0 to determine whether you are on an even or odd iteration. Concatenate the word on every even iteration (using an if statement).
If you get something like Index out of range -1, manipulate the input string by adding a space to the end.
Remember to structure the loop such that, regardless of the whether it is an even or odd iteration, the counter increases by 1.
You could alternatively remove the odd words instead of concatenation the even words, but that would be more difficult.
Not sure how you want to handle things like multiple spaces between words or weird non-alphabetically characters in the entry but this should take care of the main use case:
import java.util.Scanner;
public class HW2Q1 {
public static void main(String[] args)
{
System.out.println("Enter a sentence");
// get input and convert it to a list
Scanner keyboard = new Scanner(System.in);
String sentence = keyboard.nextLine();
String[] sentenceList = sentence.split(" ");
// iterate through the list and write elements with odd indices to a String
String returnVal = new String();
for (int i = 1; i < sentenceList.length; i+=2) {
returnVal += sentenceList[i] + " ";
}
// print the string to the console, and remove trailing whitespace.
System.out.println(returnVal.trim());
}
}

Word in a java string

I am very new to Java and as a starter I have been offered to try this at home.
Write a program that will find out number of occurences of a smaller string in a bigger string as a part of it as well as an individual word.
For example,
Bigger string = "I AM IN AMSTERDAM", smaller string = "AM".
Output: As part of string: 3, as a part of word: 1.
While I did nail the second part (as a part of word), and even had my go at the first one (searching for the word as a part of the string), I just don't seem to figure out how to crack the first part. It keeps on displaying 1 for me with the example input, where it should be 3.
I have definitely made an error- I'll be really grateful if you could point out the error and rectify it. As a request, I am curious learner- so if possible (at your will)- please provide an explanation as to why so.
import java.util.Scanner;
public class Program {
static Scanner sc = new Scanner(System.in);
static String search,searchstring;
static int n;
void input(){
System.out.println("What do you want to do?"); System.out.println("1.
Search as part of string?");
System.out.println("2. Search as part of word?");
int n = sc.nextInt();
System.out.println("Enter the main string"); searchstring =
sc.nextLine();
sc.nextLine(); //Clear buffer
System.out.println("Enter the search string"); search = sc.nextLine();
}
static int asPartOfWord(String main,String search){
int count = 0;
char c; String w = "";
for (int i = 0; i<main.length();i++){
c = main.charAt(i);
if (!(c==' ')){
w += c;
}
else {
if (w.equals(search)){
count++;
}
w = ""; // Flush old value of w
}
}
return count;
}
static int asPartOfString(String main,String search){
int count = 0;
char c; String w = ""; //Stores the word
for (int i = 0; i<main.length();i++){
c = main.charAt(i);
if (!(c==' ')){
w += c;
}
else {
if (w.length()==search.length()){
if (w.equals(search)){
count++;
}
}
w = ""; // Replace with new value, no string
}
}
return count;
}
public static void main(String[] args){
Program a = new Program();
a.input();
switch(n){
case 1: System.out.println("Total occurences: " +
asPartOfString(searchstring,search));
case 2: System.out.println("Total occurences: " +
asPartOfWord(searchstring,search));
default: System.out.println("ERROR: No valid number entered");
}
}
}
EDIT: I will be using the loop structure.
A simpler way would be to use regular expressions (that probably defeats the idea of writing it yourself, although learning regexes is a good idea because they are very powerful: as you can see the core of my code is 4 lines long in the countMatches method).
public static void main(String... args) {
String bigger = "I AM IN AMSTERDAM";
String smaller = "AM";
System.out.println("Output: As part of string: " + countMatches(bigger, smaller) +
", as a part of word: " + countMatches(bigger, "\\b" + smaller + "\\b"));
}
private static int countMatches(String in, String regex) {
Matcher m = Pattern.compile(regex).matcher(in);
int count = 0;
while (m.find()) count++;
return count;
}
How does it work?
we create a Matcher that will find a specific pattern in your string, and then iterate to find the next match until there is none left and increment a counter
the patterns themselves: "AM" will find any occurrence of AM in the string, in any position. "\\bAM\\b" will only match whole words (\\b is a word delimiter).
That may not be what you were looking for but I thought it'd be interesting to see another approach. An technically, I am using a loop :-)
Although writing your own code with lots of loops to work things out may execute faster (debatable), it's better to use the JDK if you can, because there's less code to write, less debugging and you can focus on the high-level stuff instead of the low level implementation of character iteration and comparison.
It so happens, the tools you need to solve this already exist, and although using them requires knowledge you don't have, they are elegant to the point of being a single line of code for each method.
Here's how I would solve it:
static int asPartOfString(String main,String search){
return main.split(search, -1).length - 1;
}
static int asPartOfWord(String main,String search){
return main.split("\\b" + search + "\\b", -1).length - 1
}
See live demo of this code running with your sample input, which (probably deliberately) contains an edge case (see below).
Performance? Probably a few microseconds - fast enough. But the real benefit is there is so little code that it's completely clear what's going on, and almost nothing to get wrong or that needs debugging.
The stuff you need to know to use this solution:
regex term for "word boundary" is \b
split() takes a regex as its search term
the 2nd parameter of split() controls behaviour at the end of the string: a negative number means "retain blanks at end of split", which handle the edge case of the main string ending with the smaller string. Without the -1, a call to split would throw away the trailing blank in this edge case.
You could use Regular Expressions, try ".*<target string>.*" (Replace target string with what you are searching for.
Have a look at the Java Doc for "Patterns & Regular Expressions"
To search for the occurrences in a string this could be helpful.
Matcher matcher = Pattern.compile(".*AM.*").matcher("I AM IN AMSTERDAM")
int count = 0;
while (matcher.find()) {
count++;
}
Here's an alternative (and much shorter) way to get it to work using Pattern and Matcher,or more commonly known as regex.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CountOccurances {
public static void main(String[] args) {
String main = "I AM IN AMSTERDAM";
String search = "AM";
System.out.printf("As part of string: %d%n",
asPartOfString(main, search));
System.out.printf("As part of word: %d%n",
asPartOfWord(main, search));
}
private static int asPartOfString(String main, String search) {
Matcher m = Pattern.compile(search).matcher(main);
int count = 0;
while (m.find()) {
count++;
}
return count;
}
private static int asPartOfWord(String main, String search) {
// \b - A word boundary
return asPartOfString(main, "\\b" + search + "\\b");
}
}
Output:
As part of string: 3
As part of word: 1
For the first part of your Exercise this should work:
static int asPartOfWord(String main, String search) {
int count = 0;
while(main.length() >= search.length()) { // while String main is at least as long as String search
if (main.substring(0,search.length()).equals(search)) { // if String main from index 0 until exclusively search.length() equals the String search, count is incremented;
count++;
}
main = main.substring(1); // String main is shortened by cutting off the first character
}
return count;
You may think about the way you name variables:
static String search,searchstring;
static int n;
While search and searchstring will tell us what is meant, you should write the first word in lower case, every word that follows should be written with the first letter in upper case. This improves readability.
static int n won't give you much of a clue what it is used for if you read your code again after a few days, you might use something more meaningful here.
static String search, searchString;
static int command;

Space Replacement for Float/Int/Double

I am working on a class assignment this morning and I want to try and solve a problem I have noticed in all of my team mates programs so far; the fact that spaces in an int/float/double cause Java to freak out.
To solve this issue I had a very crazy idea but it does work under certain circumstances. However the problem is that is does not always work and I cannot figure out why. Here is my "main" method:
import java.util.Scanner; //needed for scanner class
public class Test2
{
public static void main(String[] args)
{
BugChecking bc = new BugChecking();
String i;
double i2 = 0;
Scanner in = new Scanner(System.in);
System.out.println("Please enter a positive integer");
while (i2 <= 0.0)
{
i = in.nextLine();
i = bc.deleteSpaces(i);
//cast back to float
i2 = Double.parseDouble(i);
if (i2 <= 0.0)
{
System.out.println("Please enter a number greater than 0.");
}
}
in.close();
System.out.println(i2);
}
}
So here is the class, note that I am working with floats but I made it so that it can be used for any type so long as it can be cast to a string:
public class BugChecking
{
BugChecking()
{
}
public String deleteSpaces(String s)
{
//convert string into a char array
char[] cArray = s.toCharArray();
//now use for loop to find and remove spaces
for (i3 = 0; i3 < cArray.length; i3++)
{
if ((Character.isWhitespace(cArray[i3])) && (i3 != cArray.length)) //If current element contains a space remove it via overwrite
{
for (i4 = i3; i4 < cArray.length-1;i4++)
{
//move array elements over by one element
storage1 = cArray[i4+1];
cArray[i4] = storage1;
}
}
}
s = new String(cArray);
return s;
}
int i3; //for iteration
int i4; //for iteration
char storage1; //for storage
}
Now, the goal is to remove spaces from the array in order to fix the problem stated at the beginning of the post and from what I can tell this code should achieve that and it does, but only when the first character of an input is the space.
For example, if I input " 2.0332" the output is "2.0332".
However if I input "2.03 445 " the output is "2.03" and the rest gets lost somewhere.
This second example is what I am trying to figure out how to fix.
EDIT:
David's suggestion below was able to fix the problem. Bypassed sending an int. Send it directly as a string then convert (I always heard this described as casting) to desired variable type. Corrected code put in place above in the Main method.
A little side note, if you plan on using this even though replace is much easier, be sure to add an && check to the if statement in deleteSpaces to make sure that the if statement only executes if you are not on the final array element of cArray. If you pass the last element value via i3 to the next for loop which sets i4 to the value of i3 it will trigger an OutOfBounds error I think since it will only check up to the last element - 1.
If you'd like to get rid of all white spaces inbetween a String use replaceAll(String regex,String replacement) or replace(char oldChar, char newChar):
String sBefore = "2.03 445 ";
String sAfter = sBefore.replaceAll("\\s+", "");//replace white space and tabs
//String sAfter = sBefore.replace(' ', '');//replace white space only
double i = 0;
try {
i = Double.parseDouble(sAfter);//parse to integer
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
System.out.println(i);//2.03445
UPDATE:
Looking at your code snippet the problem might be that you read it directly as a float/int/double (thus entering a whitespace stops the nextFloat()) rather read the input as a String using nextLine(), delete the white spaces then attempt to convert it to the appropriate format.
This seems to work fine for me:
public static void main(String[] args) {
//bugChecking bc = new bugChecking();
float i = 0.0f;
String tmp = "";
Scanner in = new Scanner(System.in);
System.out.println("Please enter a positive integer");
while (true) {
tmp = in.nextLine();//read line
tmp = tmp.replaceAll("\\s+", "");//get rid of spaces
if (tmp.isEmpty()) {//wrong input
System.err.println("Please enter a number greater than 0.");
} else {//correct input
try{//attempt to convert sring to float
i = new Float(tmp);
}catch(NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
System.out.println(i);
break;//got correct input halt loop
}
}
in.close();
}
EDIT:
as a side note please start all class names with a capital letter i.e bugChecking class should be BugChecking the same applies for test2 class it should be Test2
String objects have methods on them that allow you to do this kind of thing. The one you want in particular is String.replace. This pretty much does what you're trying to do for you.
String input = " 2.03 445 ";
input = input.replace(" ", ""); // "2.03445"
You could also use regular expressions to replace more than just spaces. For example, to get rid of everything that isn't a digit or a period:
String input = "123,232 . 03 445 ";
input = input.replaceAll("[^\\d.]", ""); // "123232.03445"
This will replace any non-digit, non-period character so that you're left with only those characters in the input. See the javadocs for Pattern to learn a bit about regular expressions, or search for one of the many tutorials available online.
Edit: One other remark, String.trim will remove all whitespace from the beginning and end of your string to turn " 2.0332" into "2.0332":
String input = " 2.0332 ";
input = input.trim(); // "2.0332"
Edit 2: With your update, I see the problem now. Scanner.nextFloat is what's breaking on the space. If you change your code to use Scanner.nextLine like so:
while (i <= 0) {
String input = in.nextLine();
input = input.replaceAll("[^\\d.]", "");
float i = Float.parseFloat(input);
if (i <= 0.0f) {
System.out.println("Please enter a number greater than 0.");
}
System.out.println(i);
}
That code will properly accept you entering things like "123,232 . 03 445". Use any of the solutions in place of my replaceAll and it will work.
Scanner.nextFloat will split your input automatically based on whitespace. Scanner can take a delimiter when you construct it (for example, new Scanner(System.in, ",./ ") will delimit on ,, ., /, and )" The default constructor, new Scanner(System.in), automatically delimits based on whitespace.
I guess you're using the first argument from you main method. If you main method looks somehow like this:
public static void main(String[] args){
System.out.println(deleteSpaces(args[0]);
}
Your problem is, that spaces separate the arguments that get handed to your main method. So running you class like this:
java MyNumberConverter 22.2 33
The first argument arg[0] is "22.2" and the second arg[1] "33"
But like other have suggested, String.replace is a better way of doing this anyway.

Categories

Resources