How to iterate backwards through an array? - arrays

I want to take each value from the end of the array and iterate backwards to the middle of the array, adding each value to a string:
for (int x = testArray.length - 1; x > testArray.length/2; x--){
b+=testArray[x];
}
It doesn't seem to work because when I print b it is an empty space. Is it possible to iterate backwards through an array and add the values to a string. They are all String values.

One thing to note is that if the array's length is an odd number, then your code wont work, since the length divided by 2 would be a decimal. Convert the middle index to an int. You should be using StringBuilder too if you're using quite a bit of concatenations.
String[] names = {", and Henry, ", ", David", "Bob"};
StringBuilder allNames = new StringBuilder();
for (int i = names.length - 1; i >= (int) names.length/2; i--)
{
allNames.append(names[i]);
}
System.out.println(allNames);

String b = "";
for (int x = testArray.length - 1; x > testArray.length/2; x--){
b+=testArray[x];
}
System.out.println(b);

Related

Simulate strrev() function, crazy output

I should simulate the operation of the strrev() function with an inscription from me. However, I don't understand why I have a series of special characters that don't make sense as output until you stop the program completely. I also tried to see if the problem was in the index "i" with the commented line of code, but it's ok. What could be the problem? thanks!
void strrev_new(char *s_to_rev) {
int i = 0;
int length = 0;
length = strlen(s_to_rev);
for (i = 0; i < length; i++) {
s_to_rev[length - i] = s_to_rev[i];
// printf("%d ----- %d\n", (length-i), i);
}
}
You have an off-by-one error, since strlen() returns the length of the string (e.g. 5 for hello), but the last index in the string is 4 (counting from 0).
Try
s_to_rev[length - 1 - i] = s_to_rev[i];
Your code has two problems. The first, brilliantly spotted by #AKX, is that you write starting from str[length] character instead of str[length-1] (in C array indexes start from 0).
The second problem is a consequence of the fact you are trying to reverse the string in place, that is without using a auxiliary array.
With the loop
for (i = 0; i < length; i++) {
s_to_rev[length - i] = s_to_rev[i];
}
you correctly start updating the last elements of the array. But as soon as you reach the half of the string, the characters at s_to_rev[i] are not the original ones anymore, as you updated them previously!
Try instead traversing half the string and swapping characters (just use a temporary char variable):
for (i = 0; i < length/2; i++) {
char tmp = s_to_rev[length - i -1],
s_to_rev[length - i -1] = s_to_rev[i];
s_to_rev[i] = tmp;
}

String to Character Array

I have a problem with my code below:
public class stringToChar {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
char[] sCharArr;
String[] odd = new String[n];
String[] even = new String[n];
for(int i = 0; i < n; i++) {
sCharArr = in.next().toCharArray();
for(int j = 0; j < sCharArr.length; j++) {
if(j % 2 == 0)
even[i] += sCharArr[j];
else
odd[i] += sCharArr[j];
}
}
for(int i = 0; i < n; i++) {
System.out.println(even[i] + " " + odd[i]);
}
}
}
My issue is on the output it has a Null in the result. Here is a sample scenario:
2
John
Cena
Answer should be:
Jh on
Cn ea
But my code answer is:
NullJh Nullon
NullCn Nullea
Your problem is that the new arrays are initialized with all null Strings. Then your code is not assigning values to all array elements, but just to some of them!
Finally you print your array, and surprise, those values that were null and that have not been changed - are still null (and when you print a null string ... it prints "null" [ yes, null, not Null; you got a little mistake there in your output example ]
You see, you iterate from 0 to the length of your two arrays. And if the number is even, you put a value in the even[i]; and if the value is odd, it goes to odd[i]. Lets take even - in that case, odd[i] simply stays null!
One way to fix that:
List<String> even = new ArrayList<>();
List<String> odd = new ArrayList<>();
And now, instead of setting a certain index in even/odd; you simply do:
even.add(some new value);
and to add those single characters:
even.add(new String(sCharArr));
Doing so, even and odd will (in the end) contain exactly the values that you added to each list; but no "residual" nulls. For the record: the way how you split up strings, to then pull them back into a String array isn't exactly the most simple/straight forward way to solve the problem.
But I leave "further" simplifications" as exercise to the user.

Can someone please explain this line

K_count = (K_count < (byte)(CharacterMask[0][(customKey - '0') - 1][0]) ? ++K_count : 1);
It is a part of this simple code, and i cant understand how precisely does it work?
this basically increments through the available options on a standard US telephone keypad for the "3" key, looping back to the first option after the last is reached. it does so by referencing a 3-dimensional array containing the options for each key layed out as row/column/options. it is written in such a way that it can be reused for other keys with minor modifications.
the "...?...:..." construct is basically a shortcut for if/else. so you can rewrite the statement like this:
if (K_count < (byte)(CharacterMask[0][(customKey - '0') - 1][0])) {
K_count = ++K_count;
} else {
K_count = 1;
}
the "++" operator simply adds 1 to the variable, so you can rewrite as:
if (K_count < (byte)(CharacterMask[0][(customKey - '0') - 1][0])) {
K_count = K_count + 1;
} else {
K_count = 1;
}
CharacterMask is a 3-dimensional array that describes a typical telephone keypad. the first 2 dimensionsindicate the row and column of the keypad. the third dimension contains the options available on that key. so, for example, the 3 key on a telephone has 4 options (3,d,e, and f). for some reason, the author also includes the option count as the first item in the array (index 0). so CharacterMask[0][2] would give you an array containing the number 4 followed by the characters '3','d','e', and 'f'. as such, CharacterMask[0][2][0] will return the number 4. similarly CharacterMask[0][2][1] would return the char '3'. since this line of code is only really concerned with the number of options, not their values, the final array index is hard-coded to 0. given that, you can rewrite the code like this to clarify:
rowIndex = 0;
columnIndex = (customKey - '0') - 1;
optionCountIndex = 0;
if (K_count < (byte)(CharacterMask[rowIndex][columnIndex][optionCountIndex])) {
K_count = K_count + 1;
} else {
K_count = 1;
}
since customKey is a char and not a number, we can use the "-" operator to subtract the '0' char. this implicitly casts both values to a byte and returns the difference between those bytes. since the numbers are ordered 0-9 in most character sets, this effectively gets us the numerical value of the character stored in the customKey variable (e.g. char 3 becomes byte 3). so the code can be rewritten as follows:
rowIndex = 0;
keyNumber = (customKey - '0');
columnIndex = keyNumber - 1;
optionCountIndex = 0;
if (K_count < (byte)(CharacterMask[rowIndex][columnIndex][optionCountIndex])) {
K_count = K_count + 1;
} else {
K_count = 1;
}
since they keys 1,2,3 are found in columns 0,1,2 in a zero-based indexed column count, we need to subtract 1 from the keyNumber to get the column index as shown above
because CharacterMask is a char array, we need to cast the first value to a byte to get the value initially entered back. this rewrite clarifies that:
rowIndex = 0;
keyNumber = (customKey - '0');
columnIndex = keyNumber - 1;
optionCountIndex = 0;
optionCountAsCharType = (CharacterMask[rowIndex][columnIndex][optionCountIndex]);
if (K_count < (byte)optionCountAsCharType) {
K_count = K_count + 1;
} else {
K_count = 1;
}
the comparison with K_count relies on the fact that the option array length is equal to the option count plus 1. since it is zero-based indexed, that means the last index is equal to the option count. so as long as the current K_count (aka option index) is less than the option count, you can still add 1 without exceeding the max index value. but if you are on the last index, you must roll back to 1 (the index of the first option). it could be made more clear with one more refactor:
rowIndex = 0;
keyNumber = (customKey - '0');
columnIndex = keyNumber - 1;
optionCountIndex = 0;
optionCountAsCharType = (CharacterMask[rowIndex][columnIndex][optionCountIndex]);
nextIndexIsInsideArrayBounds = K_count < (byte)optionCountAsCharType
if (nextIndexIsInsideArrayBounds) {
K_count = K_count + 1;
} else {
K_count = 1;
}
You can expand that single line of code to:
int temp = (byte)(CharacterMask[0][(customKey - '0') - 1][0]);
if ( K_count < temp )
{
K_count = ++K_count;
// This is bad. See the comment about sequence points.
// It should be
K_count = K_count + 1;
}
else
{
K_count = 1;
}
(customKey - '0') - 1
This takes the value of customKey, subtracts the ASCII value of "0" (0x30), and then subtracts 1 from that.
CharacterMask[0][x][0]
This takes the 0th element of CharacterMask, takes the xth element of the result, and then takes the 0th element of that result.
(byte)x
This truncates x to its 8 least significant bits.
K_count < x
This is true (i.e. non-zero) if K_count is less than x.
x ? y : z;
This results in y if x is true, otherwise it results in z.
As to what it actually does, that depends on what CharacterMask and customKey are.

Concat LPSTR in C

Trying to use as basic C as I can to build a list of numbers from 1-52 in a random order (deck of cards). Everything works, but all of my attempts to concat the strings and get a result end in failure. Any suggestions? NOTE: This is not homework it's something I'm using to create a game.
// Locals
char result[200] = ""; // Result
int card[52]; // Array of cards
srand(time(0)); // Initialize seed "randomly"
// Build
for (int i=0; i<52; i++) {
card[i] = i; // fill the array in order
}
// Shuffle cards
for (int i=0; i<(52-1); i++) {
int r = i + (rand() % (52-i));
int temp = card[i]; card[i] = card[r]; card[r] = temp;
}
// Build result
for (int c=0; c<52; c++) {
// Build
sprintf(result, "%s%d", result, card[c]);
// Comma?
if ( c < 51 )
{
sprintf(result, "%s%s", result, ",");
}
}
My end result is always garbled text. Thanks for the help.
You keep writing to the same position of "result".
sprintf is not going to do the appending for you.
You may consider, after each sprintf, get the return value (which is the number of char written), and increment the pointer to result buffer. i.e. something like:
(psuedo code):
char result[200];
char * outputPtr = result;
for (int c=0; c<52; c++) {
// Build
int n = sprintf(outputPtr, "%d%s", card[c], (c<51 ? "," : ""));
outputPtr += n;
}
Are we writing C++ or C? In C++, concat-ing a string is just:
string_out = string_a + string_b
…since you'd be using std::string.
Furthermore, if this is C++, the STL has a std::shuffle function.
If this is C, note that all your sprintfs aren't concatenating strings, they're just overwriting the old value.
I think, if memory serves, that sprintf will always write into the buffer starting at byte 0. This means that you would be writing the first couple of bytes over and over again with a number, then a comma, then a number. Check if your first bytes are ",[0-9]" - if so, that's your issue.
This would add a comma between each number in the result string:
// Get a pointer to the result string
char* ptr = &result[0];
for (int c = 0; c < 52; c++) {
// Add each cards number and increment the pointer to next position
ptr += sprintf(ptr, "%d", card[c]);
// Add a separator between each number
if (c < 51) {
*ptr++ = ',';
}
}
// Make sure the result string is null-terminated
*ptr = 0;

Permutations for digits represented by Phone Number

I have an interview in 2 days and I am having a very hard time finding a solutions for this question:
What I want to do is .. for any phone number .. the program should print out all the possible strings it represents. For eg.) A 2 in the number can be replaced by 'a' or 'b' or 'c', 3 by 'd' 'e' 'f' etc. In this way how many possible permutations can be formed from a given phone number.
I don't want anyone to write code for it ... a good algorithm or psuedocode would be great.
Thank you
This is the popular correspondence table:
d = { '2': "ABC",
'3': "DEF",
'4': "GHI",
'5': "JKL",
'6': "MNO",
'7': "PQRS",
'8': "TUV",
'9': "WXYZ",
}
Given this, or any other d, (executable) pseudocode to transform a string of digits into all possible strings of letters:
def digstolets(digs):
if len(digs) == 0:
yield ''
return
first, rest = digs[0], digs[1:]
if first not in d:
for x in digstolets(rest): yield first + x
return
else:
for x in d[first]:
for y in digstolets(rest): yield x + y
tweakable depending on what you want to do for characters in the input string that aren't between 2 and 9 included (this version just echoes them out!-).
For example,
print list(digstolets('1234'))
in this version emits
['1ADG', '1ADH', '1ADI', '1AEG', '1AEH', '1AEI', '1AFG', '1AFH', '1AFI',
'1BDG', '1BDH', '1BDI', '1BEG', '1BEH', '1BEI', '1BFG', '1BFH', '1BFI',
'1CDG', '1CDH', '1CDI', '1CEG', '1CEH', '1CEI', '1CFG', '1CFH', '1CFI']
Edit: the OP asks for more explanation, here's an attempt. Function digstolets (digits to letters) takes a string of digits digs and yields a sequence of strings of characters which can be letters or "non-digits". 0 and 1 count as non-digits here because they don't expand into letters, just like spaces and punctuations don't -- only digits 2 to 9 included expand to letters (three possibilities each in most cases, four in two cases, since 7 can expand to any of PQRS and 9 can expand to any of WXYZ).
First, the base case: if nothing is left (string digs is empty), the only possible result is the empty string, and that's all, this recursive call is done, finished, kaput.
If digs is non-empty it can be split into a "head", the first character, and a "tail", all the rest (0 or more characters after the first one).
The "head" either stays as it is in the output, if a non-digit; or expands to any of three or four possibilities, if a digit. In either case, the one, three, or four possible expansions of the head must be concatenated with every possible expansion of the tail -- whence, the recursive call, to get all possible expansions of the tail (so we loop over all said possible expansion of the tail, and yield each of the one, three, or four possible expansions of the head concatenated with each possible expansion of the tail). And then, once again, th-th-that's all, folks.
I don't know how to put this in terms that are any more elementary -- if the OP is still lost after THIS, I can only recommend a serious, total review of everything concerning recursion. Removing the recursion in favor of an explicitly maintained stack cannot simplify this conceptual exposition -- depending on the language involved (it would be nice to hear about what languages the OP is totally comfortable with!), recursion elimination can be an important optimization, but it's never a conceptual simplification...!-)
If asked this in an interview, I'd start by breaking the problem down. What are the problems you have to solve?
First, you need to map a number to a set of letters. Some numbers will map to different numbers of letters. So start by figuring out how to store that data. Basically you want a map of a number to a collection of letters.
Once you're there, make it easier, how would you generate all the "words" for a 1-digit number? Basically how to iterate through the collection that's mapped to a given number. And how many possibilities are there?
OK, now the next step is, you've got two numbers and want to generate all the words. How would you do this if you were just gonna do it manually? You'd start with the first letter for the first number, and the first letter for the second number. Then go to the next letter for the second number, keeping the first letter for the first, etc. Think about it as numbers (basically indices into the collections for two numbers which each map to 3 letters):
00,01,02,10,11,12,20,21,22
So how would you generate that sequence of numbers in code?
Once you can do that, translating it to code should be trivial.
Good luck!
Another version in Java.
First it selects character arrays based on each digit of the phone number. Then using recursion it generates all possible permutations.
public class PhonePermutations {
public static void main(String[] args) {
char[][] letters =
{{'0'},{'1'},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'},
{'M','N','O'},{'P','Q','R','S'},{'T','U','V'},{'W','X','Y','Z'}};
String n = "1234";
char[][] sel = new char[n.length()][];
for (int i = 0; i < n.length(); i++) {
int digit = Integer.parseInt("" +n.charAt(i));
sel[i] = letters[digit];
}
permutations(sel, 0, "");
}
public static void permutations(char[][] symbols, int n, String s) {
if (n == symbols.length) {
System.out.println(s);
return;
}
for (int i = 0; i < symbols[n].length; i ++) {
permutations(symbols, n+1, s + symbols[n][i]);
}
}
}
This is a counting problem, so it usually helps to find a solution for a smaller problem, then think about how it expands to your general case.
If you had a 1 digit phone number, how many possibilities would there be? What if you had 2 digits? How did you move from one to the other, and could you come up with a way to solve it for n digits?
Here's what I came up with:
import java.util.*;
public class PhoneMmemonics {
/**
* Mapping between a digit and the characters it represents
*/
private static Map<Character,List<Character>> numberToCharacters = new HashMap<Character,List<Character>>();
static {
numberToCharacters.put('0',new ArrayList<Character>(Arrays.asList('0')));
numberToCharacters.put('1',new ArrayList<Character>(Arrays.asList('1')));
numberToCharacters.put('2',new ArrayList<Character>(Arrays.asList('A','B','C')));
numberToCharacters.put('3',new ArrayList<Character>(Arrays.asList('D','E','F')));
numberToCharacters.put('4',new ArrayList<Character>(Arrays.asList('G','H','I')));
numberToCharacters.put('5',new ArrayList<Character>(Arrays.asList('J','K','L')));
numberToCharacters.put('6',new ArrayList<Character>(Arrays.asList('M','N','O')));
numberToCharacters.put('7',new ArrayList<Character>(Arrays.asList('P','Q','R')));
numberToCharacters.put('8',new ArrayList<Character>(Arrays.asList('T','U','V')));
numberToCharacters.put('9',new ArrayList<Character>(Arrays.asList('W','X','Y','Z')));
}
/**
* Generates a list of all the mmemonics that can exists for the number
* #param phoneNumber
* #return
*/
public static List<String> getMmemonics(int phoneNumber) {
// prepare results
StringBuilder stringBuffer = new StringBuilder();
List<String> results = new ArrayList<String>();
// generate all the mmenonics
generateMmemonics(Integer.toString(phoneNumber), stringBuffer, results);
// return results
return results;
}
/**
* Recursive helper method to generate all mmemonics
*
* #param partialPhoneNumber Numbers in the phone number that haven't converted to characters yet
* #param partialMmemonic The partial word that we have come up with so far
* #param results total list of all results of complete mmemonics
*/
private static void generateMmemonics(String partialPhoneNumber, StringBuilder partialMmemonic, List<String> results) {
// are we there yet?
if (partialPhoneNumber.length() == 0) {
//Printing the pnemmonics
//System.out.println(partialMmemonic.toString());
// base case: so add the mmemonic is complete
results.add(partialMmemonic.toString());
return;
}
// prepare variables for recursion
int currentPartialLength = partialMmemonic.length();
char firstNumber = partialPhoneNumber.charAt(0);
String remainingNumbers = partialPhoneNumber.substring(1);
// for each character that the single number represents
for(Character singleCharacter : numberToCharacters.get(firstNumber)) {
// append single character to our partial mmemonic so far
// and recurse down with the remaining characters
partialMmemonic.setLength(currentPartialLength);
generateMmemonics(remainingNumbers, partialMmemonic.append(singleCharacter), results);
}
}
}
Use recursion and a good data structure to hold the possible characters. Since we are talking numbers, an array of array would work.
char[][] toChar = {{'0'}, {'1'}, {'2', 'A', 'B', 'C'}, ..., {'9', 'W', 'X'. 'Y'} };
Notice that the ith array in this array of arrays holds the characters corresponding to the ith button on the telephone. I.e., tochar[2][0] is '2', tochar[2][1] is 'A', etc.
The recursive function will take index as a parameter. It will have a for loop that iterates through the replacement chars, replacing the char at that index with one from the array. If the length equals the length of the input string, then it outputs the string.
In Java or C#, you would want to use a string buffer to hold the changing string.
function recur(index)
if (index == input.length) output stringbuffer
else
for (i = 0; i < tochar[input[index]].length; i++)
stringbuffer[index] = tochar[input[index]][i]
recur(index + 1)
A question that comes to my mind is the question of what should 0 and 1 become in such a system? Otherwise, what you have is something where you could basically just recursively go through the letters for each value in the 2-9 range for the simple brute force way to churn out all the values.
Assuming normal phone number length within North America and ignoring special area codes initially there is also the question of how many digits represent 4 values instead of 3 as 7 and 9 tend to get those often unused letters Q and Z, because the count could range from 3^10 = 59,049 to 4^10 = 1,048,576. The latter is 1024 squared, I just noticed.
The OP seems to be asking for an implementation as he is struggling to understand the pseudocode above. Perhaps this Tcl script will help:
array set d {
2 {a b c}
3 {d e f}
4 {g h i}
5 {j k l}
6 {m n o}
7 {p q r s}
8 {t u v}
9 {w x y z}
}
proc digstolets {digits} {
global d
set l [list]
if {[string length $digits] == 0} {
return $l
}
set first [string index $digits 0]
catch {set first $d($first)}
if {[string length $digits] == 1} {
return $first
}
set res [digstolets [string range $digits 1 end]]
foreach x $first {
foreach y $res {
lappend l $x$y
}
}
return $l
}
puts [digstolets "1234"]
#include <sstream>
#include <map>
#include <vector>
map< int, string> keyMap;
void MakeCombinations( string first, string joinThis , vector<string>& eachResult )
{
if( !first.size() )
return;
int length = joinThis.length();
vector<string> result;
while( length )
{
string each;
char firstCharacter = first.at(0);
each = firstCharacter;
each += joinThis[length -1];
length--;
result.push_back(each);
}
first = first.substr(1);
vector<string>::iterator begin = result.begin();
vector<string>::iterator end = result.end();
while( begin != end)
{
eachResult.push_back( *begin);
begin++;
}
return MakeCombinations( first, joinThis, eachResult);
}
void ProduceCombinations( int inNumber, vector<string>& result)
{
vector<string> inputUnits;
vector<string> finalres;
int number = inNumber;
while( number )
{
int lastdigit ;
lastdigit = number % 10;
number = number/10;
inputUnits.push_back( keyMap[lastdigit]);
}
if( inputUnits.size() == 2)
{
MakeCombinations(inputUnits[0], inputUnits[1], result);
}
else if ( inputUnits.size() > 2 )
{
MakeCombinations( inputUnits[0] , inputUnits[1], result);
vector<string>::iterator begin = inputUnits.begin();
vector<string>::iterator end = inputUnits.end();
begin += 2;
while( begin != end )
{
vector<string> intermediate = result;
vector<string>::iterator ibegin = intermediate.begin();
vector<string>::iterator iend = intermediate.end();
while( ibegin != iend)
{
MakeCombinations( *ibegin , *begin, result);
//resultbegin =
ibegin++;
}
begin++;
}
}
else
{
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
keyMap[1] = "";
keyMap[2] = "abc";
keyMap[3] = "def";
keyMap[4] = "ghi";
keyMap[5] = "jkl";
keyMap[6] = "mno";
keyMap[7] = "pqrs";
keyMap[8] = "tuv";
keyMap[9] = "wxyz";
keyMap[0] = "";
string inputStr;
getline(cin, inputStr);
int number = 0;
int length = inputStr.length();
int tens = 1;
while( length )
{
number += tens*(inputStr[length -1] - '0');
length--;
tens *= 10;
}
vector<string> r;
ProduceCombinations(number, r);
cout << "[" ;
vector<string>::iterator begin = r.begin();
vector<string>::iterator end = r.end();
while ( begin != end)
{
cout << *begin << "," ;
begin++;
}
cout << "]" ;
return 0;
}
C program:
char *str[] = {"0", "1", "2abc", "3def", "4ghi", "5jkl", "6mno", "7pqrs", "8tuv", "9wxyz"};
const char number[]="2061234569";
char printstr[15];
int len;
printph(int index)
{
int i;
int n;
if (index == len)
{
printf("\n");
printstr[len] = '\0';
printf("%s\n", printstr);
return;
}
n =number[index] - '0';
for(i = 0; i < strlen(str[n]); i++)
{
printstr[index] = str[n][i];
printph(index +1);
}
}
Call
printph(0);

Resources