Java code for finding element for attribute - java

I am writing a java code for finding element Ex.food for any attribute(attr)Ex.description in XML.
What I have done
I am taking first char of attr as start position and then checking if it equals to "<" .From this point I am looping to ignore white space,tab etc and proceed to append valid char till I find another white space,tab.But this is not working.It is supposed to find the first word after "<" and print that only .But its actually going till the end from the the point it find first char after "<"
Note:I cannot use XML parsers like DOM etc
XML
<breakfast_menu>
<food name="Belgian Waffles" price="$5.95" discount="20"
description="Two" calories="650" />
</breakfast_menu>
for (int k = start_position; k >= 0; k--) {
char testChar = xmlInString.charAt(k);
String temp = Character.toString(testChar);
if ("<".equals(temp)) {
System.out.println(k + "value of k");
for (int j = k + 1; j >= 0; j++) {
char appendChar = xmlInString.charAt(j);
String temp1 = Character.toString(appendChar);
if(!("".equals(temp1))) {
System.out.println(j + " " + appendChar);
}
}
}
}
I made few changes now and its working as expected.i.e giving first word after "<". If you have any suggestion please let me know.
int k, j, l;
for (k = start_position; k >= 0; k--) {
char testChar = xmlInString.charAt(k);
String temp = Character.toString(testChar);
if ("<".equals(temp)) {
break;
}
}
for (j = k + 1; j <= start_position; j++) {
char appendChar = xmlInString.charAt(j);
String temp1 = Character.toString(appendChar);
if (!("".equals(temp1))) {
break;
}
}
for (l = j; l <= start_position; l++) {
char appendChar1 = xmlInString.charAt(l);
String temp2 = Character.toString(appendChar1);
if (" ".equals(temp2)) {
break;
}
}
System.out.println(xmlInString.substring(j, l));

I think this will help
String str = "<food name=\"Belgian Waffles\" price=\"$5.95\" discount=\"20\"\n" ;
String res = str.substring(str.indexOf("<"), str.indexOf(" ", str.indexOf("<") + "<".length()) + " ".length());
System.out.println(res);
output
<food

Your inner while loop for (int j = k + 1; j >= 0; j++) { is broken. The condition j >= 0 doesn't make sense - j only increments so how could it ever be < 0? Instead you should be looking for the next space, tab, etc.
I don't think your solution is going to work, but that is what's wrong with the code you have posted and why it's running off the end.

Related

Getting rid of duplicates while printing a sorted string

So I have a program in java that takes a string from user input, sorts it, finds the frequencies, and prints it in alphabetical order. My only issue is that it also prints duplicates. So, if the letter d appeared three times in a string, it would print like this:
d freq: 3
d freq: 3
d freq: 3
For this project, I am not allowed to use any built-in java sorting functions (hashmaps included). Any suggestions on how to stop this? Here's my code. Thank you!
char[] charArray = userSort.toCharArray();
char tempChar;
for (int i = 0; i < charArray.length; i++) {
for (int j = 0; j < charArray.length; j++) {
if (charArray[i] < charArray[j]) {
tempChar = charArray[i];
charArray[i] = charArray[j];
charArray[j] = tempChar;
}
}
}
String sortedString = "";
for (int i = 0; i < charArray.length; i++) {
userSort += charArray[i];
}
System.out.println(sortedString + "\n");
int counter;
sortedString = "";
for (int i = 0; i < charArray.length; i++) {
counter = 0;
for (int j = 0; j < charArray.length; j++) {
if (charArray[i] == charArray[j]) {
counter++;
}
}
if (!sortedString.contains("Char: " + charArray[i])) {
if (sortedString.equals("")) {
sortedString += " " + charArray[i] + " freq: " + counter + "\n";
} else {
sortedString += " " + charArray[i] + " freq: " + counter + "\n";
}
}
}
System.out.println(sortedString);
Make sure that i != 0.
Compare charArray [i] to charArray [i-1].
If they're not equal, then print out the result.
You can use a TreeMap<Character, Integer> to keep sorted character order and for counting letter frequencies.
Map<Character, Integer> freqs = new TreeMap<>();
for (char c : charArray.length) {
freqs.put(c, 1+freqs.getOrDefault(c, 0));
}
You also don't need to sort the input string. (Especially not using bubble sort). Iterating the characters and adding/updating to the map will create the order.
What you need to do is a Bucket Sort
In brief, create a int array of length 26, which represent 26 characters (Let's call this the "counter array"
Loop through your string. For each character encountered, increment the corresponding int in the counter array.
After looping through the input string, the counter array will contains the number of occurrence for each of 26 characters
The rest should be straight-forward I believe, which you just need to loop thru the counter array and print corresponding output
Spoiler ahead: sample code. Don't read if you haven't tried to write your code
String input = "The quick brown fox jumps over a lazy dog";
int[] counter = new int[26];
for (char c : input.toLowerCase().toCharArray()) {
if (c >= 'a' && c <= 'z') {
counter[c-'a']++;
}
}
for (int i = 0; i < counter.length; ++i) {
System.out.println("" + (char)('a' + i) + " occurs " + counter[i] + " times");
}
Solution: updated without hashmap and sorting:
Algo:
1.Create temp array of 26 alphabet and put frequency count ..i.e
0-> a,
1-> b....
2.Iterate array to print the result
public static void countFrequency(){
String user = "Harshal";
user = user.toLowerCase();
char ch[]= user.toCharArray();
int arr[] = new int[26];
for(char c : ch){
arr[c-97]++;
}
for(int k=0;k<26;k++){
if(arr[k]!=0){
int val = k+97;
System.out.println((char)val + " freq: " + arr[k]);
}
}
}

Stopping a for loop without using break

I'm trying to write a program that prints all substrings of entered string. For example if user enter "rum" the output will be this:
r
u
m
ru
um
rum
import java.util.Scanner;
public class AllSubStrings
{
public static void main(String[]args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter a string: ");
String str = in.next();
String sub = "";
for(int i=0; i<str.length(); i++)
{
for(int a=0; a<str.length() ; a++)
{
if(i+a+1>str.length())break;
sub = str.substring(a,i+a+1);
System.out.println(sub);
}
}
}
}
This program works perfectly but since we didn't learn how to use "break" in classes, i'm looking for something different. Any idea apart from "break" are welcome.
Thanks in advance.
You can use this while loop cycle instead of for:
int a = 0;
while (a < str.length && i + a < str.length()) {
sub = str.substring(a, i + a + 1);
System.out.println(sub);
a++;
}
Also it is possible to replace break with return statement
Calculate how many possible substrings there can be for a certain length. For example, length 1 = 1 substring, length 2 = 3, length 3 = 6, and so on.
Then loop for that many times. There should be a generic formula you can use for no matter how long of an input string.
You don't need a break to do this task.
int len = str.length();
for (int i = 0; i < len; i++) {
for (int j = i; j < len; j++) {
System.out.println( str.substring( i, j + 1 ) );
}
}
You can have two conditions in the for loop
for(int a = 0; a < str.length() && i + a < str.length(); a++)
{
sub = str.substring(a,i+a+1);
System.out.println(sub);
}
Note that i + a + 1 <= str.length() is the same as i + a < str.length()

Write a program to print each and every alphabet with how many occured in a user input

I have to write a program to accept a String as input, and as output I'll have to print each and every alphabetical letter, and how many times each occurred in the user input. There are some constraints:
I cannot use built-in functions and collection
The printed result should be sorted by occurrence-value.
For example, with this input:
abbbccccdddddzz
I would expect this output:
a-1,z-2,b-3,c-4,d-5
This is what I have so far:
public static void isCountChar(String s) {
char c1[] = s.toCharArray();
int c3[] = new int[26];
for (int i = 0; i < c1.length; i++) {
char c = s.charAt(i);
c3[c - 'a']++;
}
for (int j = 0; j < c3.length; j++) {
if (c3[j] != 0) {
char c = (char) (j + 'a');
System.out.println("character is:" + c + " " + "count is: " + c3[j]);
}
}
}
But I don't know how to sort.
First of all a tip for your next question: The things you've stated in your comments would fit better as an edit to your question. Try to clearly state what the current result is, and what the expected result should be.
That being said, it was an interesting problem, because of the two constraints.
First of all you weren't allowed to use libraries or collections. If this wasn't a constraint I would have suggested a HashMap with character as keys, and int as values, and then the sorting would be easy.
Second constraint was to order by value. Most people here suggested a sorting like BubbleSort which I agree with, but it wouldn't work with your current code because it would sort by alphabetic character instead of output value.
With these two constraints it is probably best to fake key-value pairing yourself by making both an keys-array and values-array, and sort them both at the same time (with something like a BubbleSort-algorithm). Here is the code:
private static final int ALPHABET_SIZE = 26;
public static void isCountChar(String s)
{
// Convert input String to char-array (and uppercase to lowercase)
char[] array = s.toLowerCase().toCharArray();
// Fill the keys-array with the alphabet
char[] keys = new char[ALPHABET_SIZE];
for (int i = 0; i < ALPHABET_SIZE; i++)
{
keys[i] = (char)('a' + i);
}
// Count how much each char occurs in the input String
int[] values = new int[ALPHABET_SIZE];
for (char c : array)
{
values[c - 'a']++;
}
// Sort both the keys and values so the indexes stay the same
bubbleSort(keys, values);
// Print the output:
for (int j = 0; j < ALPHABET_SIZE; j++)
{
if (values[j] != 0)
{
System.out.println("character is: " + keys[j] + "; count is: " + values[j]);
}
}
}
private static void bubbleSort(char[] keys, int[] values)
{
// BUBBLESORT (copied from http://www.java-examples.com/java-bubble-sort-example and modified)
int n = values.length;
for(int i = 0; i < n; i++){
for(int j = 1; j < (n - i); j++){
if(values[j-1] > values[j]){
// Swap the elements:
int tempValue = values[j - 1];
values[j - 1] = values[j];
values[j] = tempValue;
char tempKey = keys[j - 1];
keys[j - 1] = keys[j];
keys[j] = tempKey;
}
}
}
}
Example usage:
public static void main (String[] args) throws java.lang.Exception
{
isCountChar("TestString");
}
Output:
character is: e; count is: 1
character is: g; count is: 1
character is: i; count is: 1
character is: n; count is: 1
character is: r; count is: 1
character is: s; count is: 2
character is: t; count is: 3
Here is a working ideone to see the input and output.
some sort: easy if not easiest to understand an coding
You loop from the first element to the end -1 : element K
compare element K and element K+1: if element K>element K+1, invert them
continue loop
if you made one change redo that !

Writing a trim method

I'm writing a method to trim certain characters from a string. s1 is the actual string, and s2 is the char that you want to trim from the string. In my main method, I called:
String text = U.trim("what ?? the hell", '?');
And the rest of the code is the trim method I wrote. The problem is that whenever I put two ? marks together it only trims one of them, but if I put them apart it trims them fine. I don't know what I did wrong, and I even put print statements in the code itself to try to debug it, and if you run the code you'll see that the two question marks are at c[5] and c[6], and below the if statement if that char is a ? mark it'll replace it and print out "5;?", but I don't know why when it's comparing c[6], and the question mark it returns as false, since c[6] is a question mark. Please help.
static String trim(String s1, char s2) {
char c[] = new char[s1.length()];
String text = "";
for (int i = 0; i < s1.length(); i++) {
c[i] = s1.charAt(i);
}
for (int i = 0; i < s1.length(); i++) {
System.out.println("C" + i + ": " + c[i]);
}
for (int i = 0; i < s1.length(); i++) {
System.out.println("Start: " + i);
if (c[i] == s2) {
System.out.println(i + ";" + s2);
for (int j = i; j < s1.length(); j++) {
if (j != s1.length() - 1) {
c[j] = c[j + 1];
} else {
c[j] = '\0';
}
}
}
}
for (int i = 0; i < c.length; i++) {
text = text + c[i];
}
return text;
}
I try the pattern class, it didn't trim the question marks.
String text = "Hello ????";
text.replaceAll(Pattern.quote("?"), "");
System.out.println(text);
You can use s1.replace("?", "")
This is similar to replaceAll, but replaceAll uses a regex.
replace() replaces all occurances in the string.
Now, as to what you did wrong:
When you found a match in the character array, you shift the remaining characters towards the head.
Starting with "abc??def", your first match is at i=3.
You shift all the remaining characters to get "abc?def"
Then, you increment i to 4, and carry on.
c[4] is 'd' at this point.
So, the error is that when you shifted the characters to the left, you still increment i anyway, causing the first shifted character to be skipped.

Creating word pairs, triplets etc for evaluation in Bleu

I need to create a list of word pairs, triplets etc for evaluation in the Bleu metric. Bleu starts with unigrams (a single word) and goes up to N-grams - the N being specified at runtime.
For example, given the sentence
"Israeli officials are responsible for airport security"
For unigrams it would just be a list of the words. For bigrams it would be
Israeli officials
officials are
are responsible
responsible for
for airport
airport security
The relevant trigrams are
Israeli officials are
officials are responsible
are responsible for
responsible for aiport
for airport security
I've coded a working Bleu that hard codes the NGrams to 4 and brute forces the calculations of the unigrams etc. It's ugly as hell, and besides, I need to be able to supply the N at run time.
The snippet that's trying to generate the pairs / triplets etc -
String current = "";
int temp = 0;
for (int i = 0; i < goldWords.length - N_GRAM_ORDER; i++) {
current = current + ":" + goldWords[i];
while (temp < N_GRAM_ORDER) {
current = current + ":" + goldWords[temp + i];
temp++;
}
goldNGrams.add(current);
current = "";
temp = 0;
}
}
Edit - so the output from this snippet should be for bigrams -
israeli:officials
officials:are
are:responsible
responsible:for
for:airport
airport:security
Where goldWords is a String array containing the individual words to be made into NGrams.
I've been tinkering with this loop for days, drawing out the relationships etc and it just won't click for me. Can anyone see what I'm doing wrong?
I would change this:
String current = "";
int temp = 0;
for (int i = 0; i < goldWords.length - N_GRAM_ORDER; i++) {
current = current + ":" + goldWords[i];
while (temp < N_GRAM_ORDER) {
current = current + ":" + goldWords[temp + i];
temp++;
}
goldNGrams.add(current);
current = "";
temp = 0;
}
}
to this:
String current = "";
for (int i = 0; i < goldWords.length(); i++){
for (int j = 0; j < N_GRAM_ORDER; j++){
if (i + j < goldWords.length())
current += ":" + goldWords[i + j];
}
goldNGrams.add(current);
current = "";
}
So, the outer for loop iterates through the first word to be included, the inner loop iterates through all the words to be included. One thing to note is that the if statement is used to prevent an array out of bounds error. This should be moved to outside the inner for loop if you only want complete n-grams.
With the if statement where it is you will get:
Israeli:officials
officials:are
are:responsible
responsible:for
for:airport
airport:security
security
If you want:
Israeli:officials
officials:are
are:responsible
responsible:for
for:airport
airport:security
instead, try this code:
String current = "";
for (int i = 0; i < goldWords.length(); i++){
if (i + N_GRAM_ORDER < goldWords.length()){
for (int j = 0; j < N_GRAM_ORDER; j++){
current += ":" + goldWords[i + j];
}
}
goldNGrams.add(current);
current = "";
}
(the above code is done without checking it against the compiler, so there might be an Off By One or minor syntax error in it. Validate it, but it will get you close).
Here's an alternative that uses a String[] to collect the ngrams instead of a string. I changed the number of iterations on the outer for loop to ensure it captures the last n-gram.
public static List<String[]> ngrams(String[] gold, int n_length) {
List<String[]> list = new ArrayList<String[]>();
for (int i = 0; i < gold.length - (n_length-1); i++) {
String[] ngram = new String[n_length];
for(int j = 0; j < n_length; j++) {
ngram[j] = gold[i+j];
}
list.add(ngram);
}
return list;
}
according to the N_GRAM programming output
int N_GRAM_ORDER = 3, temp = 0, i;
for (i = 0; i <= goldWords.length - N_GRAM_ORDER; i += N_GRAM_ORDER) {
while (temp < N_GRAM_ORDER) {
current = current + ":" + goldWords[temp + i];
temp++;
}
goldGrams.add(current);
current = "";
temp = 0;
}
if ((temp + i) < goldWords.length) {
temp += i;
while (temp < goldWords.length) {
current = current + ":" + goldWords[temp++];
}
goldGrams.add(current);
}
}
output
Israeli:officials:are
responsible:for:airport
security

Categories