I am creating a method that creates a file that contains the Strings from another file that can have anything( ints, doubles... ). I am using another method that returns true if the input its a String.
public static void buscarFichero(String ftx){
File f = new File(ftx);
Scanner s = null;
PrintWriter p = null;
try{
s = new Scanner(f).useLocale(Locale.US);
p = new PrintWriter(ftx + "_nuevo");
while(s.hasNextLine()){
String aux = s.nextLine();
if(esString(aux) == true){
String b = aux.trim();
p.println(b);
}
}
}catch(FileNotFoundException e){}
finally{
if(s != null){ s.close(); }
if(p != null){ p.close(); }
}
}
public static boolean esString(String x){
if(x.equals(x.toString())){ return true;}
else{ return false; }
}
I know I am using and auxiliar that it is always making the nextLine into a String, but I have not the knowledge to fix it. I want to get rid of everything that it is not a String
Everything you read from a file is going to technically be a String. I believe that what you are trying to accomplish is to distinguish whether or not a particular String contains only letters. If this is true then what you need to do is compare the character codes. In this example I check if the character is not a character from a-z or A-Z. If so, then it is not a word.
private static boolean isWord(String str) {
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
return false;
}
}
return true;
}
Related
Here is a description:
"Write a program that, given an input sentence, alternates the case of every alphabetic character, starting with uppercase. Spaces and non-alphabetical characters should be added to the final output as is, i.e. they should not be taken into account when alternating between upper/lowercase."
Here is what I've tried and does not work (System.out.println in main method should return correct sentence):
public class Main {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
BufferedReader in = new BufferedReader(reader);
String line;
while ((line = in.readLine()) != null) {
System.out.println(changeToUppercaseOrLowercase(countLettersWithSpaces(line), line));
}
}
private static int countLettersWithSpaces(String sentence) {
int count = 0;
for (int i = 0; i < sentence.length(); i ++)
{
char c = Character.toUpperCase(sentence.charAt(i));
if (c >= 'A' && c <= 'Z' || c == ' ' )
count ++;
}
return count;
}
private static String changeToUppercaseOrLowercase(int countLetters, String sentence) {
StringBuilder stringBuilder = new StringBuilder();
for(int i=0; i<countLetters; i++) {
if (!sentence.substring(i,i+1).equals(" ")) {
if ((i % 2) == 0) {
stringBuilder.append(sentence.substring(i,i+1).toUpperCase());
}
else {
stringBuilder.append(sentence.substring(i,i+1).toLowerCase());
}
}
if (sentence.substring(i,i+1).equals(" ")) {
stringBuilder.append(" ");
i++;
}
}
return stringBuilder.toString();
}
}
But tests says that:
Input data:
We are the world
Expected result:
We ArE tHe WoRlD
Result:
We Re He OrLd
How to solve that? Thank you in advance!
You can use Character.isAlphabetic and keep a counter that is incremented each time a letter is encountered.
public static String alternateCase(String str){
int count = 0;
StringBuilder sb = new StringBuilder(str.length());
for(int i = 0; i < str.length(); i++){
char c = str.charAt(i);
if(Character.isAlphabetic(c))
sb.append(++count % 2 == 1 ? Character.toUpperCase(c) : Character.toLowerCase(c));
else sb.append(c);
}
return sb.toString();
}
use Character.isLetter() function to check if it's a letter or not. half your problem will be solved.
and your problem description and test case doesnt go with each other. Please try to clarify more.
There are many ways to fix this. This one has minimal impact on your existing code.
Use an evenOdd counter to ensure you are not skipping over characters but still maintaining the alternation.
private static String changeToUppercaseOrLowercase(int countLetters, String sentence) {
StringBuilder stringBuilder = new StringBuilder();
int evenOdd = 0; // init ********HERE*******
for(int i=0; i<countLetters; i++) {
if (!sentence.substring(i,i+1).equals(" ")) {
if ((evenOdd % 2) == 0) { // check ********HERE*******
stringBuilder.append(sentence.substring(i,i+1).toUpperCase());
}
else {
stringBuilder.append(sentence.substring(i,i+1).toLowerCase());
}
}
if (sentence.substring(i,i+1).equals(" ")) {
stringBuilder.append(" ");
evenOdd--; // adjust to preserve proper alternation ********HERE*********
}
evenOdd++; // the normal update ********HERE*******
}
return stringBuilder.toString();
}
The input is a (good) example((eo)--)e). I have used an iterative way.
I tried with the following code:
public String scartaParentesi(String s)
{
ups = s.replaceAll("\\([^()]*\\)", "");
return ups;
}
The output of this code is a example(--)e).
The expected output is a examplee).
Based on description and comments, you can do:
String str = "a (good) example((eo)--)e";
StringBuilder stringBuilder = new StringBuilder();
int openedParenthesesCount = 0;
for (char c : str.toCharArray()) {
if (c == '(') {
openedParenthesesCount++;
} else if (c == ')') {
openedParenthesesCount--;
} else if (openedParenthesesCount == 0) {
stringBuilder.append(c);
}
}
System.out.println(stringBuilder);
Output:
a examplee
Assumption - number of '(' equals to number of ')'.
A more robust solution without any assumptions of the number of opening and closing braces:
String text = "a (good) example((eo)--)e)";
StringBuilder outText = new StringBuilder();
Deque<Character> stack = new ArrayDeque<Character>();
int i=0;
while (i<text.length()) {
if (text.charAt(i) == '(') {
stack.addFirst(text.charAt(i));
i++;
}
while (!stack.isEmpty()) {
if (text.charAt(i) != ')') {
stack.addFirst(text.charAt(i));
i++;
} else {
if (stack.removeFirst() == '(') {
i++;
}
}
}
outText.append(text.charAt(i));
i++;
}
Output:
before: a (good) example((eo)--)e)
after: a examplee)
You can also use your original String replaceAll method by putting it on a loop, replacing the same pattern on the last updated string. The break condition of the loop will be checking if 2 consecutive iterations output the same string, i.e. no pattern to replace:
String prev = text.replaceAll("\\([^()]*\\)", "");
while (!text.equals(prev)) {
prev = text;
text = text.replaceAll("\\([^()]*\\)", "");
}
System.out.println("after2: " + text);
In Java I have a json string and I want to remove the extra white spaces from it. I don't want to remove the space from the character in keys and values.
Actual JSON string
{ "Error" : "Invalid HTTP Method" , "ErrorCode" : "405" , "ErrorDesc" : "Method Not Allowed" }
Required JSON
{"Error":"Invalid HTTP Method","ErrorCode":"405","ErrorDesc":"Method Not Allowed"}
An even simpler an safer solution would be to use the Gson library (Only a few lines needed):
public static String simplify(String json) {
Gson gson = new GsonBuilder().create();
JsonElement el = JsonParser.parseString(json);
return gson.toJson(el);
}
and you can even reverse the entire process (adding spaces) with Gson's pretty printing option:
public static String beautify(String json) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonElement el = JsonParser.parseString(json);
return gson.toJson(el);
}
Hope this will help you
You get the latest version from here:
Gson Maven Repository
I´d go with something like this:
public static void main(String[] args) {
String json = "{ \"Error\": \"Inv\\\"alid HTTP Method\", \"ErrorCode\":\"405\",\"ErrorDesc\":\"Method Not Allowed\"}";
System.out.println(removeWhitespaces(json));
}
public static String removeWhitespaces(String json) {
boolean quoted = false;
boolean escaped = false;
String out = "";
for(Character c : json.toCharArray()) {
if(escaped) {
out += c;
escaped = false;
continue;
}
if(c == '"') {
quoted = !quoted;
} else if(c == '\\') {
escaped = true;
}
if(c == ' ' &! quoted) {
continue;
}
out += c;
}
return out;
}
Testrun returns
{"Error":"Invalid HTTP Method","ErrorCode":"405","ErrorDesc":"Method Not Allowed"}
What #Fabian Z said would probably work, but could be optimized (You don't need to convert the entire String to a char array first to iterate it and you should also use a StringBuilder):
public static String removeWhitespaces(String json) {
boolean quoted = false;
StringBuilder builder = new StringBuilder();
int len = json.length();
for (int i = 0; i < len; i++) {
char c = json.charAt(i);
if (c == '\"')
quoted = !quoted;
if (quoted || !Character.isWhitespace(c))
builder.append(c);
}
return builder.toString();
}
Also when using
Character.isWhitespace(c)
it will also remove line breaks
Don't forget about escaped quotes \"!
static String minimize(String input){
StringBuffer strBuffer = new StringBuffer();
boolean qouteOpened = false;
boolean wasEscaped = false;
for(int i=0; i<input.length(); i++){
char c = input.charAt(i);
if (c == '\\') {
wasEscaped = true;
}
if(c == '"') {
qouteOpened = wasEscaped ? qouteOpened : !qouteOpened;
}
if(!qouteOpened && (c == ' ')){
continue;
}
if (c != '\\') {
wasEscaped = false;
}
strBuffer.append(c);
}
return strBuffer.toString();
}
If you are using a JsonWriter to create that Json code, you could do
jsonWriter.setIndent("");
to remove all whitespaces in json code (Tested with Gson's Json Writer)
Ok this is probably my final answer to this post:
public static CharSequence removeWhitespaces(CharSequence json) {
int len = json.length();
StringBuilder builder = new StringBuilder(len);
boolean escaped = false, quoted = false;
for (int i = 0; i < len; i++) {
char c = json.charAt(i);
if (c == '\"') {
if (!escaped) quoted = !quoted;
else escaped = false;
} else if (quoted && c == '\\') {
escaped = true;
}
if (quoted || c != ' ') {
builder.append(c);
}
}
return builder;
}
Or if you want to assure that you got rid of all whitespace characters then use:
public static CharSequence removeWhitespaces(CharSequence json) {
int len = json.length();
StringBuilder builder = new StringBuilder(len);
boolean escaped = false, quoted = false;
for (int i = 0; i < len; i++) {
char c = json.charAt(i);
if (c == '\"') {
if (!escaped) quoted = !quoted;
else escaped = false;
} else if (quoted && c == '\\') {
escaped = true;
}
if (quoted || !Character.isWhitespace(c)) {
builder.append(c);
}
}
return builder;
}
This method is way more efficient than to first convert the string into a Json structure and back to a string, because that would be way to time consuming.
Telling the StringBuilder in advance which start capacity it should have also speeds up the process by a lot, if you have a long input String.
(Capacity is not equals to length, meaning that even if you tell the StringBuilder eg. it should have a capacity of 100 it will still only have a length of the text you put into it)
And since StringBuilder implements CharSequence you can directly return the entire StringBuilder instead of converting it back to a String. But if you need a String and not a CharSequence, just call builder.toString(); at the end of this method and set the return type to String.
It ignores consonants.
It ignores any type of space.
It ignores case.
The only thing it cannot ignore is if another vowel occurs out of order.
These count:
AEIOU,
aeiou,
hahehihohu,
Take it out
These do not:
AEIuO,
Taco is good,
Take it over
Here is what I have so far:
import java.util.Scanner;
public class AEIOU_Counter {
public static void main(String[] args) throws Exception {
java.io.File file = new java.io.File("vowels.txt");
Scanner input = new Scanner(file);
String fileContent = "";
while (input.hasNext())
{
fileContent += input.next() + " ";
}
input.close();
char[] charArr = fileContent.toCharArray();
int counter = 0;
for (char c : charArr)
{
if(c == 'a' || c == 'e' ||c == 'i' ||c == 'o' ||c == 'u')
counter++;
}
System.out.println("The file " + file + " has AEIOU in order " + counter + " times");
}
}
The problem is the output:
The file vowels.txt has AEIOU in order 50 times
However, the file vowels.txt contains:
AEIOU aeiou baeiboeu bbbaaaaaa beaeiou caeuoi ajejijoju aeioo
aeiOu ma me mi mo mu take it OUT!
So the correct output should be:
The file vowels.txt has AEIOU in order 8 times
theres two ways i can think to do it. No real code since this is your assignment :)
first way is to edit the input to be as simple as possible.
1. Read input from file
2. toLowerCase() the input (to make "aEiOU" simplar as just "aeiou")
3. Remove all non-vowel characters. (so that 'hahehihohu' becomes 'aeiou')
4. Search for literal string "aeiou" and count occurrances.
Second way is leave the input alone, but use loops and counters. the 'sequence' could be an array, or a linked list maybe
sequence = [a,e,i,o,u] // (or a->e->i->o->u)
curr_char_of_sequence = 'a'
counter = 0
for each char in the input, loop {
if the char is not a vowel {
continue to next char
}
//see if the vowel is the one we want next
if char == curr_char_of_sequence {
//it is! update whats the next vowel we want.
// ie, if we were looking for an 'a', now look for an 'e'
curr_char_of_sequence = sequence.next
//check to see if we reached the end of the sequence, if so, we found a completed 'aeiou' set
if curr_char_of_sequence == invalid {
counter++
curr_char_of_sequence = 'a'
}
//we found a vowel that isn't the right one, restart the sequence
} else {
curr_char_of_sequence = 'a'
}
}
As people pointed out, you should use regular expression.
Here is a little help to get you every AEIOU in this specific order (doesn't ignore the non vowels in between)
java.io.File file = new java.io.File("vowels.txt");
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String fileContent = "";
while (input.hasNext())
{
fileContent += input.next().toLowerCase();
}
input.close();
int counter = 0;
for (int i = 0; i<fileContent.length()-4;i++)
{
if(fileContent.charAt(i) == 'a'){
if(fileContent.charAt(i+1)=='e'){
if(fileContent.charAt(i+2)=='i')
if(fileContent.charAt(i+3)=='o')
if(fileContent.charAt(i+4)=='u'){
counter++;
}
}
}
}
System.out.println("The file " + file + " has AEIOU in order " + counter + " times");
}
Of course, it counts every times theres ONE of these letters. (a OR e OR i...)
Try using booleans, if u have a letter ("a"), u look for the next ("e").
for (char c : charArr)
{
if(c == 'a') {
boolA = true;
}
else if(c=='e') {
if (boolA) {
boolE = true;
}
else {
boolA = false;
boolE = false;
boolI = false;
boolO = false;
boolU = false;
}
}
else if (c=='i') {
if (boolE) {
boolI = true;
}
else {
boolA = false;
boolE = false;
boolI = false;
boolO = false;
boolU = false;
}
//etc, etc ....
}
if u understand what i mean ^^
Or, there is the other way (for the lazy dudes)
u remember the last valide character u found, and if the actual letters follows it, it's won.
char lastChar;
String validLetters = "aeiou";
String myArray = "eiou"; //i removed the first
for (char c : charArr) {
if (c=='a') {
lastChar=='a';
}
else if ( validLetters.contains(c) && lastChar==validLetters.charAt(myArray.indexOf(c)) ) {
lastChar = c; //u understand it, u get the answer ^^
}
else {
lastChar='w' //just a random char, not in AEIOU
}
the last one is better,
Hope it helps, Bye :)
Looks like Me Good Guy beat me to it, but here is a full example with the boolean idea
public static void main(String[] args) {
boolean a = false;
boolean e = false;
boolean i = false;
boolean o = false;
boolean u = false;
int vowelCounter = 0;
String s = "AEIOU aeiou hahehihohu Take it out";
for (int index = 0; index < s.length(); index++) {
Character c = Character.toLowerCase(s.charAt(index));
if (c == 'a') {
a = true;
continue;
}
if (a && c == 'e') {
e = true;
continue;
}
if (a && e && c == 'i') {
i = true;
continue;
}
if (a && e && i && c == 'o') {
o = true;
continue;
}
if (a && e && i && o && c == 'u') {
u = true;
// no continue because we want to exit this if-chain
}
if (a && e && i && o && u) {
vowelCounter++;
a = e = i = o = u = false; // reset
}
}
System.out.printf("The string \"%s\" contains 'aeiou' in order %d times.\n", s, vowelCounter);
// The string "AEIOU aeiou hahehihohu Take it out" contains 'aeiou' in order 4 times.
}
I used the following code to count the number of comments in a code:
StringTokenizer stringTokenizer = new StringTokenizer(str);
int x = 0;
while (stringTokenizer.hasMoreTokens()) {
if (exists == false && stringTokenizer.nextToken().contains("/*")) {
exists = true;
} else if (exists == true && stringTokenizer.nextToken().contains("*/")) {
x++;
exists = false;
}
}
System.out.println(x);
It works if comments have spaces:
e.g.: "/* fgdfgfgf */ /* fgdfgfgf */ /* fgdfgfgf */".
But it does not work for comments without spaces:
e.g.: "/*fgdfgfgf *//* fgdfgfgf*//* fgdfgfgf */".
Using StringUtils class in commons lang, you can very easily archive this
String str = "Your String"
if (&& StringUtils.countMatches(str,"/*") != 0) {
//no need this if condition
} else if (StringUtils.countMatches(str,"*/") != 0) {
x = StringUtils.countMatches(str,"*/");
}
System.out.println(x);
new StringTokenizer(str,"\n") tokenizes/splits str into lines rather than using the default delimiter which is \t\n\r\f, a combination of spaces, tabs, formfeed, carriage and newline
StringTokenizer stringTokenizer = new StringTokenizer(str,"\n");
This specifies newline as the only delimiter to use for Tokenizing
Using your current approach:
String line;
while(stringTokenizer.hasMoreTokens()){
line=stringTokenizer.nextToken();
if(!exists && line.contains("/*")){
exists = true;
}
if(exists && line.contains("*/")){
x++;
exists = false;
}
}
For multiple comments I tried to use /\\* & \\*/ as patterns in split() and got length for their occurrence in the string, but unfortunately length were not exact due to uneven splitting.
Multiple/Single Comments can be: (IMO)
COMMENT=/* .* */
A = COMMENT;
B = CODE;
C = AB/BA/ABA/BAB/AAB/BAA/A;
This reminds me of flip-flops in Ruby/Perl/Awk et al. There is no need to use a StringTokenizer. You just need to keep states to count the number of lines with comments.
You are inside a comment block. You start printing or collecting all the characters. As soon as you encounter a */ in its entirety you toggle the comment block switch. And switch to state 2
You reject everything until you encounter a /* and are back to state 1.
Something like this
public static int countLines(Reader reader) throws IOException {
int commentLines = 0;
boolean inComments = false;
StringBuilder line = new StringBuilder();
for (int ch = -1, prev = -1; ((ch = reader.read())) != -1; prev = ch) {
System.out.println((char)ch);
if (inComments) {
if (prev == '*' && ch == '/') { //flip state
inComments = false;
}
if (ch != '\n' && ch != '\r') {
line.append((char)ch);
}
if (!inComments || ch == '\n' || ch == '\r') {
String actualLine = line.toString().trim();
//ignore lines which only have '*/' in them
commentLines += actualLine.length() > 0 && !"*/".equals(actualLine) ? 1 : 0;
line = new StringBuilder();
}
} else {
if (prev == '/' && ch == '*') { //flip state
inComments = true;
}
}
}
return commentLines;
}
public static void main(String[] args) throws FileNotFoundException, IOException {
System.out.println(countLines(new FileReader(new File("/tmp/b"))));
}
Above program ignores empty line comments or lines with only /* or */ in them. We also need to ignore nested comments which string tokenizer may fail todo.
Example file /tmp/b
#include <stdio.h>
int main()
{
/* /******* wrong! The variable declaration must appear first */
printf( "Declare x next" );
int x;
return 0;
}
returns 1.