Java: Count duplicate tokens on line using Scanner object - java

Yes this is an exercise from "Building Java Programs", but its not an assigned problem.
I need to write a method that reads the following text as input:
hello how how are you you you you
I I I am Jack's Jack's smirking smirking smirking smirking smirking revenge
bow wow wow yippee yippee yo yippee yippee yay yay yay
one fish two fish red fish blue fish
It's the Muppet Show, wakka wakka wakka
And produces the following as output:
how*2 you*4
I*3 Jack's*2 smirking*4
wow*2 yippee*2 yippee*2 yay*3
wakka*3
Now I know I have to use Scanner objects to first read a line into a String, the to tokenize the string. What I don't get is how I read a token into a string, then immediately compare it to the next token.
CONSTRAINT -> This is from the chapter before arrays so I'd like to solve without using one.
Here is the code I have so far:
public class Exercises {
public static void main(String[] Args) throws FileNotFoundException {
Scanner inputFile = new Scanner(new File("misc/duplicateLines.txt"));
printDuplicates(inputFile);
}
public static void printDuplicates(Scanner input){
while(input.hasNextLine()){
//read each line of input into new String
String lineOfWords = input.nextLine();
//feed String into new scanner object to parse based on tokens
Scanner newInput = new Scanner(lineOfWords);
while(newInput.hasNext()){
//read next token into String
String firstWord = newInput.next();
//some code to compare one token to another
}
}
}

No need to use arrays...you just need a little bit of state in the while loop:
public class Exercises {
public static void main(String[] Args) throws FileNotFoundException {
// scanner splits on all whitespace characters by default, so it needs
// to be configured with a different regex in order to preserve newlines
Scanner inputFile = new Scanner(new File("misc/duplicateLines.txt"))
.useDelimiter("[ \\t]");
printDuplicates(inputFile);
}
public static void printDuplicates(Scanner input){
int lastWordCount = 0;
String lastWord = null;
while(newInput.hasNext()){
//read next token into String
String nextWord = newInput.next();
// reset counters on change and print out if count > 1
if(!nextWord.equals(lastWord)) {
if(lastWordCount > 1) {
System.out.println(lastWord + "*" + lastWordCount);
}
lastWordCount = 0;
}
lastWord = nextWord;
lastWordCount++;
}
// print out last word if it was repeated
if(lastWordCount > 1) {
System.out.println(lastWord + "*" + lastWordCount);
}
}
}

How about this? I'm allocating an extra string to keep track of the previous word.
while(input.hasNextLine()){
//read each line of input into new String
String lineOfWords = input.nextLine();
//feed String into new scanner object to parse based on tokens
Scanner newInput = new Scanner(lineOfWords);
String previousWord = "";
String currentWord = "";
while(newInput.hasNext()){
//read next token into String
previousWord = currentWord;
currentWord = newInput.next();
if (currentWord.equals(previousWord)) {
// duplicate detected!
}
}
}

public class test2 {
public static void main(String[] args) {
Scanner input = null;
try {
input = new Scanner(new File("chinese.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String currentLine;
String lastWord="";
String currentWord="";
int count=1;
while (input.hasNextLine()){
currentLine=input.nextLine();
Scanner newInput = new Scanner (currentLine);
//System.out.println(currentLine);
while(newInput.hasNext()){
currentWord=newInput.next();
if (!currentWord.equals(lastWord)&& count>1){
System.out.print(lastWord+"*"+count+" ");
count=1;
}
else if (currentWord.equals(lastWord)){
count++;
}
lastWord=currentWord;
}
if (count>1){
System.out.print(lastWord+"*"+count+" ");
}
System.out.println();
count=1;
}
input.close();
}
}

Related

Array/ArrayList to make order with scanner input

so my teacher ordered me to make a program that
ask the user for the size of the array with a scanner
the program is required to understand if there is a scanner with the word "add" it will add the word after it to the array
The commands that are required to exist are ADD, DELETE, VIEW for display index-n and DISPLAY for display all of them
this is an example I've made but it's still far from correct, please help me!!!
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a = input.nextInt();
String arr[] = new String[a];
for (int i = 0; i < a; i++) {
for (int j=0;j<arr.length;j++){
arr[i] = input.nextLine();
}
}
for( String b : arr ){
System.out.println(b);
}
enter code here
an example of the scanner input is
7
ADD this
ADD IS
ADD not
ADD real
VIEW 2
DELETE not
DISPLAY
and the output will be
not
this is real
There's no reason to ask how long the array should be because we are using ArrayList which is a dynamic array. You can make this code easier to read but here's just an example of what you are looking for:
public final static void main(final String[] args)
{
final List<String> list = new ArrayList<String>();
final Scanner scan = new Scanner(System.in);
while (true)
{
final String command = scan.nextLine().toLowerCase();
if (command.contains("add "))
{
list.add(command.replace("add ", ""));
} else if (command.contains("delete "))
{
final String toDelete = command.replace("delete ", "");
if (!list.remove(toDelete))
System.out.format("\"%s\" didn't exist in the array!", toDelete);
} else if (command.contains("view "))
{
System.out.println(list.get(Integer.parseInt(command.replace("view ", ""))));
} else if (command.equals("display"))
{
for (final String str : list)
{
System.out.println(str);
}
break;
} else
{
System.out.println("Unknown command!");
}
}
scan.close();
}

I'm trying to use the scanner with multiple lines and trying to make change the input with another string java

So, I'm trying to make a program that will ask you what you want changed, and it will ask you on what is that you're going to change, The best way to explain this is lets say that I have a bunch of 1234 in my string, and I would like to change them all to "WASD", (Please keep in mind that these multiple line inputs are stored into ArrayList) Yet, my program seems not to be working, it gives me no output back soon as i place in an input.
THIS IS MY CODE (I'm sorry I'm not following naming conventions but i hope you can get a general understanding)
package com.far.main;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class findandreplace {
static String inputLocation;
static String inputChange;
static String data;
static List<String>test1 = new ArrayList<String>();
findandreplace(){
}
public static void findthanreplace() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter what string YOU WANT TO REPLACE");
String input = scanner.nextLine();
inputLocation = input;
System.out.println("Enter the DATA you want to replace WITH");
String inputDataChange = scanner.nextLine();
inputDataChange = inputChange;
returnInput();
}
public static void returnInput() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter in the data");
while (scanner.hasNextLine()) {
List<String> test = new ArrayList<>();
Scanner scanner1 = new Scanner(scanner.nextLine());
while (scanner1.hasNext()) {
test.add(scanner1.next());
}
test = test1;
}
finalResult();
}
public static void finalResult() {
System.out.println();
System.out.println();
System.out.println(Collections.replaceAll(test1, inputLocation, inputChange));
System.out.println(test1);
}
public static void main(String[] args) {
findthanreplace();
}
}
in my opinion your code as some problem like
1) this code display you want just one line and replace so you should write break; end of while (scanner.hasNextLine()) scope because compiler never exit from while.
else you want multiple line you can get size of entered code and if size is empty break.
2) you should replace test1 = test; instead of test = test1;
3 )you can print items of list as test1.forEach(n-> System.out.print(n.concat(" "))); instead of System.out.println(test1);
so i change your code as below
public static void returnInput() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter in the data");
while (scanner.hasNextLine()) {
List<String> test = new ArrayList<>();
Scanner scanner1 = new Scanner(scanner.nextLine());
while (scanner1.hasNext()) {
test.add(scanner1.next());
}
if(test.isEmpty())
break;
test1 .addAll(test);
}
finalResult();
}
public static void finalResult() {
System.out.println();
System.out.println();
System.out.println(Collections.replaceAll(test1, inputLocation, inputChange));
test1.forEach(n-> System.out.print(n.concat(" ")));
}
There are multiple issues in your code. These should be fixed in order to get the expected results
You are not providing a condition that forces to break the loop that takes inputs from user.
You use Collections.replaceAll() which does not satisfy your requirements. As my understanding, you need to replace a substring with another, not an element with another. So, Collections.replaceAll() is not what you want in this case.
You are initializing a Scanner object inside a loop and that is not a good practice.
You have multiple redundant variable assignments. Some of these are not even used. So clean them up. Ex: test = test1;
Here's a one possible solution to avoid above problems, but seems it can be optimized futher.
static String inputLocation;
static String inputChange;
static List<String> test1 = new ArrayList<String>();
public static void findthanreplace()
{
Scanner scanner = new Scanner( System.in );
System.out.println( "Enter what string YOU WANT TO REPLACE" );
inputLocation = scanner.nextLine();
System.out.println( "Enter the DATA you want to replace WITH" );
inputChange = scanner.nextLine();
returnInput();
}
public static void returnInput()
{
Scanner scanner = new Scanner( System.in );
System.out.println( "Enter in the data" );
while( scanner.hasNextLine() )
{
String input = scanner.nextLine();
if( input.equalsIgnoreCase( "DONE" ) ) // Impose a condition to break from this loop, Ex : This loop breaks once user input is DONE
break;
test1.add( input );
}
finalResult();
}
public static void finalResult()
{
System.out.println();
System.out.println();
for( int i = 0; i < test1.size(); i++ )
{
// This line converts the inputs to lowercase and find the starting index of first appearance of the string that needs to be replaced.
Matcher m = Pattern.compile( inputLocation.toLowerCase() ).matcher( test1.get( i ).toLowerCase() );
while( m.find() )
{
int startIndex = m.start();
// Replace the substring with the desired replacement and add that to list
String replacedString = test1.get( i ).replace( test1.get( i ).substring( startIndex, inputLocation.length() ), inputChange ); String firstMatch = m.group();
test1.set( i, replacedString );
}
}
System.out.println( test1 );
}
public static void main( String[] args )
{
findthanreplace();
}

String substring error

Question:
Input:-gandhi output:- Gandhi
Input:-mahatma gandhi output:- M. Gandhi
Input:-Mohndas Karamchand ganDhi output:- M. K. Gandhi
Answer:
public class Chef_NITIKA {
static Scanner scan=new Scanner(System.in);
public static void main(String[] args) {
String name= myString();
System.out.println("nam is :"+name);
mySformatter(name);
}
private static void mySformatter(String name) {
int count=0;
for(char c:name.toCharArray()){
if(c==' '){
count+=1;
}
}
System.out.println(count+" blank spaces");
if(count==0){
char ch=name.charAt(0);
name=Character.toUpperCase(ch)+name.substring(1);
System.out.println("nam is :"+name);
}
else if(count==1){
char ch=name.charAt(0);
name= name.replace(' ', '.');
String subname=name.substring(name.indexOf(".")+1);
char c=subname.charAt(0);
subname=Character.toUpperCase(c)+subname.substring(1);
name=Character.toUpperCase(ch)+"."+subname;
System.out.println("nam is :"+name);
}
else if(count==2){
char ch=name.charAt(0);
// name= name.replace(' ', '.');
String subname=name.substring(name.indexOf(" ")+1);
System.out.println(subname);
String subsubname=subname.substring(name.indexOf(" "));
System.out.println(subsubname);
char c=subname.charAt(0);
char c1=subsubname.charAt(0);
subname=Character.toUpperCase(c)+subname.substring(1);
name = Character.toUpperCase(ch)+"."+Character.toUpperCase(c)+"."+Character.toUpperCase(c1)+subsubname.substring(1);
System.out.println("nam is :"+name);
}
}
private static String myString() {
System.out.println("enter the string");
String s=scan.nextLine();
StringBuffer name=new StringBuffer();
// name.append(s);
return s;
}
}
I am not getting the desired output when i type "abc cde fgh" i get the output as A.C..fgh
Is there any efficient way to solve this problem?
undesired output:-
enter the string
iam writing onStack
nam is :iam writing onStack
2 blank spaces
writing onStack
ing onStack
nam is :I.W.Ing onStack
I want the output as I.W.OnStack
Just split the name into components and then form the abbreviations you want:
public static String getName(String input) {
String[] names = input.split("\\s+");
String output = "";
// replace 1st through second to last names with capitalized 1st letter
for (int i=names.length; i > 1; --i) {
output += names[names.length - i].substring(0, 1).toUpperCase() + ". ";
}
// append full last name, first letter capitalized, rest lower case
output += names[names.length - 1].substring(0, 1).toUpperCase()
+ names[names.length - 1].substring(1).toLowerCase();
return output;
}
public static void main(String[] args) {
System.out.println(getName("gandhi"));
System.out.println(getName("mahatma gandhi"));
System.out.println(getName("Mohndas Karamchand ganDhi"));
}
Output:
Gandhi
M. Gandhi
M. K. Gandhi
Demo here:
Rextester
Update:
Here is a link to a demo where I have corrected your original code, at least partially. The issue was the following line:
String subsubname = subname.substring(name.indexOf(" "));
which I changed to this:
String subsubname = subname.substring(subname.indexOf(" ") + 1);
You were not correctly identifying the first character of the third portion of the name. This being said, your current approach is verbose, hard to read, and inflexible. In practice, you would probably want to use a leaner approach to this problem.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package stack;
import java.util.Scanner;
import java.util.StringTokenizer;
/**
*
* #author xxz
*/
public class NAmes {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
final String name = sc.nextLine();
System.out.println(formatedString(name));
sc.close();
}
private static String formatedString(String name) {
if(name!=null && name.length()!=0){
final StringTokenizer tokenizer = new StringTokenizer(name, " ");
StringBuilder result = new StringBuilder("");
while(tokenizer.hasMoreTokens()){
StringBuilder currentToken =new StringBuilder(tokenizer.nextToken());
if(!tokenizer.hasMoreTokens()){
result.append(currentToken.toString().toUpperCase());
} else{
result.append(currentToken.toString().toUpperCase().charAt(0)+". ");
}
}
return result.toString();
}
return "";
}
}
#Rushabh Oswal you can get desired result by below method
private static void mySformatter(String name) {
String [] tempArray=name.split(" ");
StringBuilder outputStr=new StringBuilder();
int len=tempArray.length;
for(int i=0;i<len;i++){
String str=tempArray[i];
if (str.isEmpty())
continue;
if(i==len-1)
outputStr.append(Character.toUpperCase(str.charAt(0))).append(str.substring(1).toLowerCase());
else
outputStr.append(Character.toUpperCase(str.charAt(0))).append(". ");
System.out.println(outputStr.toString());
}

Scan for duplicate strings in a file

I have been having a problem with the next step in the logic of my code. Basically I'm supposed to examine each line of a file looking for consecutive tokens on the same line, and print the duplicate token along with the number of times it consecutively occurs. Non repeated tokens aren't printed.
here's a sample file
/*
* sometext.txt
* hello how how are you you you you
I I I am Jack's Jack's smirking smirking smirking smirking revenge
bow wow wow yippee yippee yo yippee yippee yay yay yay
one fish two fish red fish blue fish
It's the Muppet Show, wakka wakka wakka
*/
and here's some code that i've written.
package chapter6;
import java.util.*;
import java.io.*;
public class OutputDuplicates {
public static void main (String[] args) throws FileNotFoundException {
for (;;) {
Scanner scan = new Scanner(System.in);
prompt(scan);
}
}
public static void prompt(Scanner scan) throws FileNotFoundException {
System.out.println("What is the name of the file?");
String name = scan.next();
File inputFile = new File(name);
if (inputFile.exists()) {
Scanner read = new Scanner(inputFile);
while (read.hasNext()) {
String line = read.nextLine();
Scanner oneLine = new Scanner (line);
while (oneLine.hasNext()) {
String word = oneLine.next();
System.out.println(word);
}
}
} else if (!inputFile.exists()) {
prompt(scan);
}
}
}
Any insight to the logic from here out would be much appreciated.
Here you go buddy, it should work for you
public Map<String, Long> scan(File file) throws Exception {
Map<String, Long> map = new HashMap<>();
Scanner read = new Scanner(file);
while (read.hasNext()) {
String line = read.nextLine();
if(map.containsKey(line)) {
map.put(line, map.get(line).longValue() + 1);
} else {
map.put(line, 1L);
}
}
return map;
}
pseudocode:
for each line in the file
{
lastword = ""
numtimes = 1
for each word in the line
{
if word == lastword
{
numtimes++
}
else
{
if numtimes > 1
{
print (/*print lastword and numtimes here*/)
}
lastword = word
numtimes = 1
}
}
}
You want to make a symbol frequency table:
Map<String, Integer> symbolFrequencies = new HashMap<String, int>();
Then for each symbol, do this:
Integer countForSymbol = symbolFrequencies.get(symbol);
if (countForSymbol==null){
symbolFrequencies.put(symbol, 1);
} else {
countForSymbol = new Integer(countForSymbol.intValue + 1);
}
and that's it. You will now have counts for all the symbols you have parsed.

Permutations of a string

public class Permute {
public static void main(String[] args) throws IOException {
System.out.println("Enter a string");
BufferedReader bufReader = new BufferedReader(new InputStreamReader(System.in));
String text = bufReader.readLine();
shuffle("",text);
}
public static void shuffle(String dummy, String input){
if(input.length() <= 1)
System.out.println(dummy+input);
else{
for(int i=0; i <input.length();i++){
input = input.substring(i,1) + input.substring(0,i) + input.substring(i+1);
shuffle(dummy+input.substring(0,1),input.substring(1));
}
}
}
}
Am trying to print all the permutations of a string entered. And I really cannot guess where am going wrong because on paper I find that this executing. Where exactly am going wrong.
Try change your shuffle:
public static void shuffle(String dummy, String input){
if(input.length() <= 1)
System.out.println(dummy+input);
else{
for(int i=0; i <input.length();i++){
shuffle(dummy+input.charAt(i), input.substring(0, i) + input.substring(i+1, input.length()));
}
}
}
public class Permute {
public static void main(String[] args) throws IOException {
System.out.println("Enter a string");
BufferedReader bufReader = new BufferedReader(new InputStreamReader(System.in));
String text = bufReader.readLine();
shuffle("",text);
}
public static void shuffle(String dummy, String input){
if(input.length() <= 1)
System.out.println(dummy+input);
else{
for(int i=0; i <input.length();i++){
input = input.substring(i,i+1) + input.substring(0,i) + input.substring(i+1);
shuffle(dummy+input.substring(0,1),input.substring(1));
}
}
}
}
It should be input.substring(i,i+1) instead of input.substring(i,1). Because each time I need only 1 character to be constant, which is at the beginning of the string and others have to be jumbled.
The bug was I presumed the functionality of substring to be substring(beginIndex, length). But it is substring(beginIndex,endIndex).
#Oli: Thank you for the help.
Since this seems like a homework assignment I once did I will help you out here. You will need two loops, one inside the other.
for(int i;i<something;i++)
for(int j;j<somethingElse;j++)
This will enable you to generate the permutations that are required.
Replace two lines in the for loop with following:
String partString = input.substring(0, i) + input.substring(i + 1);
shuffle(dummy + input.charAt(i), partString);
Since this looks like your homework I will let you figure out. If not, will post explanation after a bit ( got to get back to my day job ;) )

Categories

Resources