|
-
Aug 25th, 2001, 08:40 PM
#1
Thread Starter
Dazed Member
need help! [resolved]
This is an assignment that one
of my friends professors gave to the class.
He wanted me to help him so i figured ok.
The decription of the assignment is down below,
but i am having trouble with this statement
while((q = x % key.length()) != ???????){
which is also down below. Any help would be cool.
Code:
create a method that takes
a String as an arguement and
returns a TreeMapwhich will map
the string and the number of
characters that occur only once
within the string. since the counting
operation can be time consuming, the
method should cache the results so that
when the method is given a string
previously encountered,it
will simply retrieve the stored result.
import java.io.*;
import java.util.*;
public class MultipleChar{
public static void main(String[] args){
for(;;){
BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
try{
System.out.println("Please enter a string");
String key = buff.readLine();
TreeMap tm = (TreeMap) checkForDuplicates(key);
System.out.println(" Within " + key + " there were " + tm.get(key) + " characters that only appeared once ");
System.out.println("Press Y if you would like to continue: " + "N if you want to exit" );
String exit = buff.readLine();
if(exit.equalsIgnoreCase("n")){System.exit(0);}
}catch(Exception e){System.err.println(e);}
}
}
public static Object checkForDuplicates(String key){
short onlyappearsonce;
short duplicates = 0;
char matchingchar;
Map stringMap = new TreeMap();
int q = 1;
int z = 0;
int x = 0;
int k = 0;
short multiplechar;
// check map to see if string is present, if it is return key
if(stringMap.containsKey(key)){return stringMap.get(key);}
for(int index = 0; index <= key.length() - 1; ++index){
matchingchar = key.charAt(index);
x = ((key.length() * key.length()) - (key.length() + 1));
System.out.println(x);
while((q = x % key.length()) != ???????){
if(matchingchar == key.charAt(++z)){
++duplicates;
}
--x;
}
z = 0;
z =+1;
}
int nonduplicatechars = (key.length() - duplicates);
Integer charcount = new Integer(nonduplicatechars);
stringMap.put(key,charcount);
return stringMap;
}
}
Last edited by Dilenger4; Oct 1st, 2001 at 03:14 PM.
-
Aug 25th, 2001, 08:43 PM
#2
Member
Re: need help!
Originally posted by Dilenger4
while((q = x % key.length()) != ???????)
Eww, icky code. Never, ever assign in an If! Bad! *smacks author* 
Anyway, that assigns q to the remainder of the division "x / key.length(). So, while the remainder is not equal to "???????" is what the thing means.
-
Aug 25th, 2001, 09:02 PM
#3
Thread Starter
Dazed Member
Yes i understand that but what would take me to the end of a string (which is named key) without causing an IndexOutofBounds exception to be thrown?
-
Aug 25th, 2001, 09:07 PM
#4
Member
What is this stupid-ass code supposed to do? I could just re-write it.
-
Aug 25th, 2001, 09:16 PM
#5
Thread Starter
Dazed Member
Just as the description says
create a method that takes
a String as an arguement and
returns a TreeMapwhich will map
the string and the number of
characters that occur only once
within the string. since the counting
operation can be time consuming, the
method should cache the results so that
when the method is given a string
previously encountered,it
will simply retrieve the stored result.
Sometimes i wonder about you Filbert
-
Aug 25th, 2001, 09:23 PM
#6
Member
Ick! I would do it in a HashMap and just spit the values to System.out. But that's just me.
-
Aug 25th, 2001, 09:28 PM
#7
Thread Starter
Dazed Member
But what would be the algorithmn that you would use to
calculate the number of characters that appear only once with in a string? i went with this and im on the right track but as you can see im a little stuck.
Code:
for(int index = 0; index <= key.length() - 1; ++index){
matchingchar = key.charAt(index);
x = ((key.length() * key.length()) - (key.length() + 1));
System.out.println(x);
while((q = x % key.length()) != ???????){
if(matchingchar == key.charAt(++z)){
++duplicates;
}
--x;
}
z = 0;
z =+1;
}
int nonduplicatechars = (key.length() - duplicates);
-
Aug 25th, 2001, 09:33 PM
#8
Member
Pseudocode (too lazy to write the real code and to test it )
BTW, if the professor is stupid and doesn't know that Java uses Unicode, you can do ASCII and just make a vector with 255 elements: one for each ASCII char.
BTW, if you've never seen the Javadocs before, use them! http://java.sun.com/j2se/1.3/docs/api/index.html They'll save your life someday.
Code:
For each character i in the string
currentchar = string[i]; // cache it for speed
add currentchar to hashmap // nuts, just looked at the HashTable JDK docs and it will not work
Next i
Grr...me try to think of something else. Methinks that professor stupidity will make this really easy...
-
Aug 25th, 2001, 09:40 PM
#9
Thread Starter
Dazed Member
http://www.vbforums.com/showthread.p...threadid=97588
This was a discussion on this and Kedaman came up with somthing but im not quite sure if i undersatand it. He used a Vector as you pointed out. (well it's really a char array[])
but trying to code an algorithmn is not easy.......
-
Aug 28th, 2001, 02:00 PM
#10
Thread Starter
Dazed Member
i think the problem i am having is that i
dont actually see where
the comparision is taking place.
For instance:
ok... here you would be filling
up an integer array with each
individual char from the string.
Incrementing the index of the
array and the index of the character
within the string at the same time.
Code:
for(int i=0; i<aString.length(); i++)
histogram[aString.charAt(i)]++;
Now here i understand "aChar = (char)i;"
where you are casting
an integer value to get the
coresponding Unicode value. But im not
seeing where the comparision is taking place.
Code:
for(int i=0; i<65536; i++){
aChar = (char)i;
if(histogram[i] != 0)
System.out.println("The count for '" + aChar + "' in '"
+ aString + "' is " + histogram[i]);
}
System.out.println();
}
Thanks for replying.
-
Aug 31st, 2001, 03:17 PM
#11
You're welcome. I've been chasing my own algorithm bugs lately. You know how it is. My recent one was being clear on what memberes needed to be static (shared) in a class which intermittently invoked its Runnable interface.
I'm not certain what you mean by "comparison". To get at the characters which only occur once from the supplied strings given on the command line, you would change
if(histogram[i] != 0)
to the following comparison
if(histogram[i] == 1)
But I "left that as an exercise" and instead showed you a more general case of developing a histogram.
If you mean,
ok... here you would be filling
up an integer array with each
individual char from the string.
The datatypes could be a source of confusion.
In
histogram[aString.charAt(i)]++;
I am incrementing the integer count (which started at zero) of the integer which represents the char with this integer value. If 68 represents the char "D", then the integer with the array element of index 68 is incremented.
histogram[aString.charAt(i)]++;
If the char at the i position of this string is D, then
aString.charAt(i) returns a char "D", but since an int index is required here to specify which index I am addressing in the histogram array, Java performs a widening converion from char to int, making the statement read as
histogram[68]++;
"Incrementing the index of the array"
The integer index of the histogram array is controlled by the value of the equivalent char to int value.
The for loop spans the length of the string (incrementing over the length of the string). The implicit cast (widening conversion) is the index. I would not say "incremented". I would say addressed or indexed.
"...and the index of the character within the string at the same time."
The for loop does the incrementing over the string. The charAt(over this increment's i position) is a char implicitly cast to int to index (address) the array element named 68. The integer at position 68 in the int array named histogram, is incremented.
Hope that clarifies things.
-
Sep 2nd, 2001, 01:10 AM
#12
Thread Starter
Dazed Member
I think the reason that i am having a hard time
understanding what you presented is that
i think you are trying to do somthing
diffrent than what i was thinking.
For some reason when i look at the
block below.Your getting the char
equivlent casted from the index.
then your printing the char "aChar", the
string and then the integer
representation of the char. I was thinking
about finding how many chars occur within the
string only one time. AABCCDEEFF = The
char B only occured in the string one time"
Code:
for(int i=0; i<65536; i++){
aChar = (char)i;
if(histogram[i] != 0)
System.out.println("The count for '" + aChar + "' in '" + aString + "' is " + histogram[i]);
}
-
Sep 2nd, 2001, 02:09 AM
#13
If we've carried out the pasting properly throughout, then change to the following:
for(int i=0; i<65536; i++){
aChar = (char)i;
if(histogram[i] == 1)//The integer at the i position in the histigram array is equal to 1. So the char with this int value equivalent only occured once.
System.out.println("The character '" + aChar + "' in '" + aString + "' occured only once.");
}
-
Sep 2nd, 2001, 03:12 PM
#14
Thread Starter
Dazed Member
I fixed my other block and it seems to work fine except
if multiple characters(three or more) are encountered.
Code:
for(int index = 0; index <= key.length() - 2; ++index){
matchingchar = key.charAt(index);
while(z < key.length()){
if(matchingchar == key.charAt(z)){
++duplicates; // for matching char
match = true;
}
++z;
}
if(match == true){
++duplicates; // for orginal char
match = false;
}
z = 0;
z = ++v;
}
int nonduplicatechars = (key.length() - duplicates);
-
Sep 2nd, 2001, 11:08 PM
#15
Did you read my last post on
== 1
regarding
histogram[i] == 1
?
-
Sep 3rd, 2001, 03:13 PM
#16
Thread Starter
Dazed Member
Yes thanks. I must have read it over
and over and over But i still dont see
how testing for equivalency to 1 ie
histogram[i] == 1
would give me the count of how
many characters only appear once within a String.
If you pass the String Cat on the
command line as an arguement,
your integer array should hold the
following (regardless of the characterset)
histogram[67]
histogram[97]
histogram[116]
Am i correct so far?
What i am have a hard time understanding
here is how and when are the values containd
in the array equal to 1?
Code:
for(int i=0; i<65536; i++){
aChar = (char)i;
if(histogram[i] == 1)//The integer at the i position in the histigram array is equal to 1. So the char with this int value equivalent only occured once.
System.out.println("The character '" + aChar + "' in '" + aString + "' occured only once.");
}
-
Sep 3rd, 2001, 03:57 PM
#17
Okay.
First, we put data into an integer array.
Second, we get data out of an integer array.
The data is simply an integer which represents the count of a particular character.
I've named the integer array "histogram" for its general uses, but you could have named it "count" as in
int[] count;
The "magic" is that an integer is interpreted as a character when the datatype is char rather than int. So this is why we see "C" instead of "67" when we print aChar versus the int i.
Try:
System.out.println("The count for '" + aChar + "' in '" + aString + "' is " + histogram[i] + " since the integer is " + i);
Yes, you are correct. For "Cat"
histogram[67] == 1
histogram[97] == 1
histogram[116] == 1
We set the elements 67, 97, and 116 of the histogram array equal to 1 when we used these lines:
for(int i=0; i<aString.length(); i++)
histogram[aString.charAt(i)]++;
It may be more clear if I said
histogram[(int)(aString.charAt(i))] = histogram[(int)(aString.charAt(i))] + 1;
But the cast is implicitly done for you by Java.
Depending on your application, you might write a separate method to retrieve the count for a specific character or retrieve the character for a specific count.
I tested the value of histogram's elements to see if they were non zero, or equal to one (initial post, recent post respectively)
Also, I think this may come back and haunt you "(regardless of the characterset)" if your app runs on a pc with a different default character encoding. But you and I are "safe" from requiring "translations to speak to each other" because we have the same character encoding (so to speak).
-
Sep 4th, 2001, 09:57 AM
#18
Thread Starter
Dazed Member
I fixed some things(method name conflicted
with class name)
and compiled your code. Works great! So simplistic i it's
design but it seems to work good.
For abbc the output is:
The count for 'a' in 'abbc' is 1
The count for 'b' in 'abbc' is 2
The count for 'c' in 'abbc' is 1
How are we actually getting the char count though?
I think it is with this line of code. But i the way i interpret
it is that we are filling each index of the integer array
with each character of the string being supplied. the ++
increments the array and .charAt(i) increments to the next
char in the String.
Code:
for(int i=0; i<aString.length(); i++){
histogram[aString.charAt(i)]++;
}
Code:
public class CharHistogram{
private static int[] histogram;
private static char aChar;
public static void Histogram(String aString){
histogram = new int[65536];//ASCII is 0-127, Unicode is 16 bits.
for(int i=0; i<aString.length(); i++){
histogram[aString.charAt(i)]++;
}
for(int i=0; i<65536; i++){
aChar = (char)i;
if(histogram[i] != 0)
System.out.println("The count for '" + aChar + "' in '" + aString + "' is " + histogram[i]);
}
System.out.println();
}
public static void main(String[] args){
for(int i=0; i<args.length; i++)
Histogram(args[i]);
}
}
-
Sep 4th, 2001, 10:47 PM
#19
How are we actually getting the char count though?
I think it is with this line of code. But i the way i interpret
it is that we are filling each index of the integer array
with each character of the string being supplied. the ++
increments the array and .charAt(i) increments to the next
char in the String.
First, let's make sure we mean "the integer count of characters" when we say "the char count".
We are not "...filling each index of the integer array
with each character..." since an int is an int and a character is a character. What we can do is count the characters with an integer datatype "int".
.charAt(i) does not increment anything, it returns a char which is a character. But this char is implicitly cast to an int. This int is an index that just happens to correspond to the location in the histogram integer array that we hold the count of this particular char. .charAt(i) in this case is an index used by the integer array named "histogram".
Once we have indexed the element in the integer array named "histogram", we increment it by the "++". It is as if we said
histogram[67]++;
For this app, we intend to interpret the integer (the int) represented by "histogram[67]" as the count of the character "C" in a string.
Later, when we see that the int at index 67 is some number, we say that this number is the number of ocurances of the letter "C".
Let's say I have 26 boxes. I label each box by one letter A to Z. But these boxes only hold numbers. If I'm given a string "CAT", when I see an A, I add 1 to the value in the box labelled A. When I see a C or a T, I increment the integer value of whatever is in the box named C or T. When I'm done "parsing" my string, I look at the numbers in each box. Whatever number is in the box, I look at the name of the box and interpret this to mean that for this letter, this many of that letter occured in my string.
Depending on the name of a "box", we say different things about a property because of the number the box contains..
If 65 is the first number in an RGB sequence, we say that is an intensity of 65 for red.
If 65 is in an ascii set, we say it is the letter A.
If 65 is in the bracket of an array, we mean the element at position 65.
If I'm using 65 for addressing in an integer array, once I've addresed the element, I'm only dealing with an int. I then increment the int at this position and later interpret this as how many A's I've counted.
histogram[65] represents the number of A's that I've counted.
I simple coding (encryption) could be to interpret the integer at a different position in an array (say by having boxes labelled 2-27 instead of 1-26 or A-Z). Then I'd interpret whatever was in box 2 to really represent the count of A's, etc. But I'd have to remember the mapping of numbers to letters for this "encryption scheme.
In this code, ABC is 66, 67, 68
Then ABBA would be encoded as BCCB or 67, 68, 68, 67 instead of the "normal" 65,66,66,65. To decode, we subtract 1 and can use that value as if it was the ascii code.
Sorry for the tangent. I hope you get it now.
-
Sep 5th, 2001, 02:49 PM
#20
Thread Starter
Dazed Member
".charAt(i) does not increment anything"
Sorry i ment incrementation within the string not the array.
I have to be careful how i word stuff. 
But i do see a similiarity between the integer representation
of the char and the integer representation of the char
in regard to the array index. It seems almost like you are
creating a charset mapping, because for an array.
int[] ISO-Latin1 = new int[255] you are saying
ISO-Latin1[s.charAt(i)]
ISO-Latin1['A']
ISO-Latin1[66]
Once we have indexed the element in the
integer array named "histogram", we increment
it by the "++". It is as if we said histogram[67]++;
Ok i see now. s.charAt(i) represents
the array index or mapping
and the use of []++ adds 1 or i
should says stores 1
in that particular index. So each time
an occurance of a particular
char is encountered within the
string we add one.
So for this block of code there really is no
comparison except
disregard for non-occurrences within
the string that we are
searching.
Code:
if(histogram[i] != 0)
System.out.println("The count for '" + aChar + "' in '" + aString + "' is " + histogram[i]);
}
Im going to read and examine the second half of your
reply because it seems extreamly interesting how
your shifting to accomplish encrypting.
-
Sep 5th, 2001, 08:38 PM
#21
Thread Starter
Dazed Member
The only thing about your code that i
dont understand is why doesnt it
loop 65536 times? It seems only
to loop the length of the string.
Code:
public class CharHistogram{
private static int[] histogram;
private static char aChar;
public static void Histogram(String aString){
histogram = new int[65536];//ASCII is 0-127, Unicode is 16 bits.
for(int i=0; i<aString.length(); i++){
histogram[aString.charAt(i)]++;
}
for(int i=0; i<65536; i++){
aChar = (char)i;
if(histogram[i] != 0)
System.out.println("The count for '" + aChar + "' in '" + aString + "' is " + histogram[i]);
}
System.out.println();
}
public static void main(String[] args){
for(int i=0; i<args.length; i++)
Histogram(args[i]);
}
}
-
Sep 6th, 2001, 05:42 PM
#22
So for this block of code there really is no
comparison except
disregard for non-occurrences within
the string that we are
searching.
Yes. That loop basically outputs characters with non-zero counts using
!=0
But in a later post I modified it to only ouput counts of 1 (which was your main application for this type of code).
==1
Regarding 65536, I declared the int array to be that large (in light of unicode), but I should get away with 128 or 256 for our english or ascii character set since that is my default unicode character encoding.
Regarding encryption, I thought you might be interested since I think I saw you asking about an encryption api. This is probably the first type encryption anybody learns about. A=1, B=2, etc.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|