Is it possible to point to the first element of a char[] in java?
I have this code in C++ as an example of what I am trying to do:
char word[100] = " ";
char *p;
cout << "Enter a word: ";
cin.getline(word, 100);
p = word + strlen(word) - 1;
Is it possible to do something like this in Java?
Thank you for your time!
Java lacks the concept of pointers, so the answer is "no". All operations on an array must be performed using indexes.
The consequence of this is that you cannot pass a single argument so methods expecting to read or write arrays starting at a certain position; you always need an array and an index.
Note: In general, C++ approaches to reading strings do not translate to Java very well, because Java I/O libraries will manage memory for you, freeing you from having to worry about buffer overruns on reading a string.
Java has no concept of pointers and Java String(s) have a fixed length (they're also immutable so they have a fixed everything).
That being said, your posted code is reading one word which you could do with a Scanner like
Scanner scan = new Scanner(System.in);
String word = scan.next(); // <-- nextLine() if you want a line.
int length = word.length();
Concept of pointers are not used in java reason been that memory release and allocation is done automatically by the java virtual machine , the only way to access an array reference is through the index
Short Answer: No
Long Answer: No... Java does not have any pointers. It only has Object references. Any non-primitive data type is pass-by-reference, meaning that if you have the following:
Object a = new Object();
Object b = a;
Object c = new Object();
a == b is true, while b == c and a == c are false.
If you want to have pointer-like behavior in Java, you need to wrap it up in an Object and use references. For example, it is possible that an AtomicInteger[] could be used, and you pass a reference to one of the AtomicIntegers, but it would probably be best to hold the int index as a 'pointer' to the location in the array. Furthermore, your snippet of code could just have a char variable, set to word[0]. It really depends on what you need a pointer for...
Related
I am writing my first app in Android Studio, I am a self-taught novice. When I write data into the subscript of an array I have created as a user-defined class the value is written into an adjacent subscript as well! Have traced to some code where I move data down one position in the array, thought I could do this in one operation, but it seems this messes something up and I need to copy each member of the class individually.
Here is my class
class LeaderboardClass
{
public String DateTime;
public String UserName;
public long Milliseconds; //0 denotes not in use
}
Here is my array declaration
LeaderboardClass[] LeaderboardData = new LeaderboardClass[LeaderboardEntries];
I want to move some data from subscript j to subscript j+1
I tried
LeaderboardData[j + 1] = LeaderboardData[j];
I thought this would copy all the data from subscript j to j+1
Then when I subsequently write to the array I (subscript i) I get the correct entry I made, plus a duplicate entry in the adjacent subscript i+1.
When I rewrite the above to:
LeaderboardData[j + 1].UserName = LeaderboardData[j].UserName;
LeaderboardData[j + 1].DateTime = LeaderboardData[j].DateTime;
LeaderboardData[j + 1].Milliseconds = LeaderboardData[j].Milliseconds;
Everything else behaves as expected. So I was wondering exactly what is happening with my first (presumably incorrect) code?
Thanks.
In Java, there's a difference between primitive values and objects (instances of classes): Primitives are stored by value whereas objects are stored by reference. This means that your code would work as you expect if you were using integers. However, since you are using a class, the array merely stores the references to those objects. Hence, when you do LeaderboardData[j + 1] = LeaderboardData[j]; you are merely copying the reference of that object. Therefore, LeaderboardData[j + 1]and LeaderboardData[j] will point to the same object.
Sidenote: If you run your program with a debugger, you can actually see this in action:
The number behind the # denotes the reference number and if you look closely, you can see that the objects at indices 8 and 9 both have the reference #716.
To fix this, I would suggest that you use lists instead of arrays as they allow you to remove and add new entries. The standard list implementation is an ArrayList but in your use-case, a LinkedList might be more efficient.
Lastly, a closing notes on your code: For variable names (like DateTime, UserName or LeaderboardData should always start with a lowercase letter to distinguish them from classes. That way, you can avoid lots of confusion - especially because Java also has a built-in class called DateTime.
I'm working on the following problem:
Gary is an avid hiker. He tracks his hikes meticulously, paying close attention to small details like topography. During his last hike he took exactly n steps.
For every step he took, he noted if it was an uphill, U, or a downhill, D step. Gary's hikes start and end at sea level and each step up or down represents a 1 unit change in altitude. We define the following terms:
A mountain is a sequence of consecutive steps above sea level, starting with a step up from sea level and ending with a step down to sea level.
A valley is a sequence of consecutive steps below sea level, starting with a step down from sea level and ending with a step up to sea level.
Given Gary's sequence of up and down steps during his last hike, find and print the number of valleys he walked through.
For example, if Gary's path is s = [DDUUUUDD], he first enters a valley 2 units deep. Then he climbs out an up onto a mountain 2 units high. Finally, he returns to sea level and ends his hike.
Function Description
Complete the countingValleys function in the editor below. It must return an integer that denotes the number of valleys Gary traversed.
countingValleys has the following parameter(s):
n: the number of steps Gary takes
s: a string describing his path
Input Format
The first line contains an integer , the number of steps in Gary's hike.
The second line contains a single string , of characters that describe his path.
Output Format
Print a single integer that denotes the number of valleys Gary walked through during his hike.
Sample Input
8
UDDDUDUU
Sample Output
1
Below is my implementation in java. It works for the small test cases but not for the big ones.
static int countingValleys(int n, String s) {
//Use a hashmap to keep track of the number of moves.
HashMap<Character,Integer> map = new HashMap();
boolean sea = true;//check if we are at sea level
//if both D and U have the same total no, we are at sea level.
map.put('D',0);
map.put('U',0);
int valleys = 0;//count num of valleys
for(int i = 0; i < n; i++){
char key = s.charAt(i);
//check if we are at sea level
if(map.get('D') == map.get('U')){//<--PROBLEM
sea = true;
}
else
sea = false;
if(sea == true && key == 'D'){//if we are at sea level and our next key is D, we have a valley
valleys += 1;
}
map.put(key,map.get(key) + 1);//add move and update our hashmap
}
return valleys;
}
The problem seems to be at "if(map.get('D') == map.get('U'))", it seems to be returning false for big numbers, can someone tell me why? It works if I assign each map.get() to a variable and compare the variables instead.
I also wrote the exact same thing in javascript using the "new Object()" type and it passed all the test cases, but it is not working in java with hashmap, why is that?
link to original problem - https://www.hackerrank.com/challenges/counting-valleys/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=warmup
First, as mentioned in other answer, use .equals() instead of == in this case. An even better approach is, you don't even need to use a Map. Just one integer will be good enough.
As your question is ...returning false for big numbers, can someone tell me why?
Here is the reason.
There are several things you need to understand
1. Types of variable
First, you need to know there are two types of variable in Java: Primitive and Reference.
An integer is usually a Primitive, so the variable itself is the integer value: int a = 1234; : a itself is having value 1234.
To compare primitive variable, you should use ==
For reference type, variable itself is a "pointer". In Java there are Wrapper Classes for primitives. For example, Integer is the wrapper for int. So in Integer a = new Integer(1234);, a is not containing value of 1234. It is a pointer pointing to an Integer object reference. Using == on reference type variables does not compare the content, but only check if the pointer value is the same (i.e. check if they point to same object instance)
2. Autoboxing
Starting from Java 1.5 (iirc), there is a feature called auto-boxing (and unboxing), which ease programmer in converting between primitive types and their corresponding wrapper.
In the past, you need to do something like this:
int a = 1234;
Integer intWrapper = new Integer(a);
int b = intWrapper.intValue();
With autoboxing, you just need to write:
int a = 1234;
Integer intWrapper = a;
int b = intWrapper;
And compiler is going to convert it to:
int a = 1234;
Integer intWrapper = Integer.valueOf(a);
int b = intWrapper.intValue();
So far so good?
Final Answer
So the reason why your code works with small number is:
Integer.valueOf() is caching frequently-used value. From API doc:
public static Integer valueOf(int i)
Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
Because it is caching the wrappers, therefore if you are doing map.put(key,map.get(key) + 1), result of get(key) + 1, which is an int, when converting to Integer and if it is a small number, will be a same instance of Integer for same int value. That means, == still works (as variables are pointing to same Integer). However if it is a not-cached number, every invocation will be a different instance, and == will not work (as variables are pointing to different instances of Integer, though the value in the Integer instances are the same)
Suggestion to your algorithm, though a bit off topic:
Your logic is over complicated. It can be greatly simplified to (pseudo code):
countValley(String s) {
currentLevel = 0
valleyCount = 0
for (step in s) {
if step == 'U' {
++currentLevel;
if (currentLevel == 0) { // returning to sea level
++valleyCount
}
} else if step == 'D' {
--currentLevel;
}
}
return valleyCount
}
to compare wrapper Class need to use .equals.
can use Objects.equals :
java.util.Objects.equals(firstInteger, secondInteger);
for case above :
if(java.util.Objects.equals(map.get('D'), map.get('U'))){
sea = true;
}
First, don't use '=='. Use .equals for all classes extends Object.
to compare content of wrapper classes (Integer, Float, Long, Double), use .equals(). "==" would compare the references of both objects. The references might be different even though both contain the same content. You will can however use "==" when you are comparing value types such as int, float, long, double.
Solution 1: If you must use a HashMap, looks like iteration in HashMap is the problem. Below a link to how to do it. As you iterate, build your logic for counting hills and valleys. How to efficiently iterate over each entry in a Java Map?.
Solution 2: Use Array instead of HashMap. After building it, find the D sequences and so on.
Is there an equivalent to Java's String intern function in Go?
I am parsing a lot of text input that has repeating patterns (tags). I would like to be memory efficient about it and store pointers to a single string for each tag, instead of multiple strings for each occurrence of a tag.
No such function exists that I know of. However, you can make your own very easily using maps. The string type itself is a uintptr and a length. So, a string assigned from another string takes up only two words. Therefore, all you need to do is ensure that there are no two strings with redundant content.
Here is an example of what I mean.
type Interner map[string]string
func NewInterner() Interner {
return Interner(make(map[string]string))
}
func (m Interner) Intern(s string) string {
if ret, ok := m[s]; ok {
return ret
}
m[s] = s
return s
}
This code will deduplicate redundant strings whenever you do the following:
str = interner.Intern(str)
EDIT: As jnml mentioned, my answer could pin memory depending on the string it is given. There are two ways to solve this problem. Both of these should be inserted before m[s] = s in my previous example. The first copies the string twice, the second uses unsafe. Neither are ideal.
Double copy:
b := []byte(s)
s = string(b)
Unsafe (use at your own risk. Works with current version of gc compiler):
b := []byte(s)
s = *(*string)(unsafe.Pointer(&b))
I think that for example Pool and GoPool may fulfill your needs. That code solves one thing which Stephen's solution ignores. In Go, a string value may be a slice of a bigger string. Scenarios are where it doesn't matter and scenarios are where that is a show stopper. The linked functions attempt to be on the safe side.
Is
char buf[] = "test";
in C equivalent to
String buf = new String("test");
in Java?
And is
char *buf;
buf = "test";
equivalent to
String buf = "test";
?
It's difficult to say they're equivalent, although I understand what you're driving at.
Your C version is a sequence of 8-bit chars. The Java variant is Unicode-aware.
Secondly, in Java you're creating an object with behaviour, rather than just a sequence of chars.
Finally, the Java variant is immutable. You can change the reference, but not the underlying set of characters (this is a function of being wrapped by the String object)
For something largely equivalent you could use an array of bytes in Java. Note that this wouldn't be null-terminated, however. Java arrays are aware of their length rather than using a convention of null-termination. Alternatively a closer C++ equivalent would probaly be std::string
This question can't really be answered - you're comparing apples to oranges.
In C, a "string" is really just a char array, that is null-terminated (that is, a '\0' byte at the end, placed by the compiler, and expected by the str__() library functions.
In Java, String is an object, that holds (possibly among other things), an array of characters, and an integer count.
They are different things, and they are used differently. Is there something specific you are trying to accomplish and having trouble with? If so, ask that, and we will try to answer it. Otherwise, this isn't really a valid question, IMO.
The first two are not equivalent. In Java, the String object, besides storing a char array, contains also other things (e.g. the length field). The java version is, of course, more OO.
The second ones are equivalent with the same observations as above. They are both pointers to containers of characters. The c container is a simple char array, while the string is a full-fledged object.
No. These are different data types. char buf[] is an array and String buf is an object. The String buf will be dynamically sized and have plenty of helpful methods with it. char buf[] is a static sized chunk of memory holding 5 8-bit characters.
Below will create an array of characters
char buf[] = "test";
Where as String buf = new String("test"); will lead to creation of a String Object, but internally its char[] itself which is made immutable internally using a String object wrapper. So its a representation difference in the above 2 programming languages.
i try to store a string into an integer as follows:
i read the characters of the string and every 4 characters i do this:
val = (int) ch << 24 | (int) ch << 16 | (int) ch << 8 | (int) ch;
Then i put the integer value in an array of integer that is called memory (=> int memory[16]).
I would like to do it in an automatic way for every length of a string, plus i have difficulties to inverse the procedure again for an arbitrary size string. Any help?
EDIT:
(from below)
Basically, i do an exercise in JAVA. It's a MIPS simulator system. I have Register, Datum, Instruction, Label, Control, APSImulator classes and others. When i try to load the program from an array to simulator's memory, i actually read every contents of the array which is called 'program' and put it in memory. Memory is 2048 long and 32 bits wide. Registers are declared also 32bit integers. So when there is an content in the array like Datum.datum( "string" ) - Datum class has IntDatum and StringDatum subclasses - i have somehow to store the "string" in the simulator's data segment of memory. Memory is 0-1023 text and 1024-2047 data region. I also have to delimit the string with a null char - plus any checkings for full memory etc. I figure out that one way to store a String to MemContents ( reference type - empty interface - implemented by class that memory field belongs to ) is to store the string every ( 2 or maybe 4 symbols ) to a register and then take the contents of the register and store it in memory. So, i found very difficult to implement that and the reverse procedure also.
If you are working in C, you have your string in a char array that is of a size multiple of a int, you can just take the pointer to the char array, cast it to a pointer to a int array and do whatever you want with your int array. If you don't have this last guarantee, you may simply write a function that creates your int array on the fly:
size_t IntArrayFromString(const char * Source, int ** Dest)
{
size_t stringLength=strlen(Source);
size_t intArrElements;
intArrElements=stringLength/sizeof(int);
if(stringLength%sizeof(int)!=0)
intArrElements++;
*Dest=(int *)malloc(intArrElements*sizeof(int));
(*Dest)[intArrElements-1]=0;
memcpy(Dest, Source, stringLength);
return intArrElements;
}
The caller is responsible for freeing the Dest buffer.
(I'm not sure if it really works, I didn't test it)
Have you considered simply using String.getBytes() ? You can then use the byte array to create the ints (for example, using the BigInteger(byte[]) constructor.
This may not be the most efficient solution, but is probably less prone to errors and more readable.
Assuming Java: You could look at the ByteBuffer class, and it's getInt method. It has a byte order parameter which you need to configure first.
Basically, i do an exercise in JAVA. It's a MIPS simulator system. I have Register, Datum, Instruction, Label, Control, APSImulator classes and others. When i try to load the program from an array to simulator's memory, i actually read every contents of the array which is called 'program' and put it in memory. Memory is 2048 long and 32 bits wide. Registers are declared also 32bit integers. So when there is an content in the array like Datum.datum( "string" ) - Datum class has IntDatum and StringDatum subclasses - i have somehow to store the "string" in the simulator's data segment of memory. Memory is 0-1023 text and 1024-2047 data region. I also have to delimit the string with a null char - plus any checkings for full memory etc. I figure out that one way to store a String to MemContents ( reference type - empty interface - implemented by class that memory field belongs to ) is to store the string every ( 2 or maybe 4 symbols ) to a register and then take the contents of the register and store it in memory. So, i found very difficult to implement that and the reverse procedure also.
One common way to do this in C is to use a union. It could look like
union u_intstr {
char fourChars[4];
int singleInt;
};
Set the chars into the union as
union u_intstr myIntStr;
myIntStr.fourChars[0] = ch1;
myIntStr.fourChars[1] = ch2;
myIntStr.fourChars[2] = ch3;
myIntStr.fourChars[3] = ch4;
and then access the int as
printf("%d\n", myIntStr.singleInt);
Edit
In your case for 16 ints the union could be extended to look like
union u_my16ints {
char str[16*sizeof(int)];
int ints[16];
};
This is what I come up with
int len = strlen(str);
int count = (len + sizeof(int))/sizeof(int);
int *ptr = (int *)calloc(count, sizeof(int));
memcpy((void *)ptr, (void *)str, count*sizeof(int));
Due to the use of calloc(), the resulting buffer has at least one NULL, maybe more to pad the last integer. This is not portable because the integers are in native byte order.