Seperate integers from 1 variable into different variables - android-studio

Not sure how to explain this the best but I have a variable with 4 int's in it. Is there a simple way to extract the 4 int's into 4 seperate var's?
Example:
The variable contains: 4567
And then the output is:
var1 = 4
var2 = 5
var3 = 6
var4 = 7

Another way can be:
val n = 4567
val (var1, var2, var3, var4) = "$n".map { it.digitToInt() }
Note that this will fail if number contains less than 4 digits.

You can do this:
val input = 4567
val var1 = input / 1000
val var2 = (input % 1000) / 100
val var3 = (input % 100) / 10
val var4 = (input % 10)

Related

Problem with Double, String and Integer conversion

Why is the value 4.49504794 ? It should be usdRate:String * sas * ddx:EditText.
I want it to be 0.00000001 * input from edittext (from user) * usdRate:String (1 BTC in USD)
It should be 0.00000001/44950 * x (user_input = x) = (0,00002224694105)
I'm also wanting to limit usdRate:String to only 5 digits total, or somehow remove the last four symbols in the string.
var usdRate:String = (JSONObject(json).getJSONObject("bpi").getJSONObject("USD")["rate"] as String)
val text = usdRate.replace(",", "")
val text2 = text.replace(".", "")
val satosh: Int = text2.toInt()
val sas: Double = 0.00000001
val sas2: Double = sas.toDouble() * satosh.toDouble()
val ddx:EditText = findViewById(R.id.editTextNumber2)
val sasEnty: Double = (ddx.text.toString().toDouble() * sas2)
//1 satoshi value in USD
usdView.text = sasEnty.toString()
//Problem end
Picture of output in application
Output
This code gave me the output I was looking for. When a user input 3 as a value, will it return 0.0013994405520000002
//ex 45,000.01234
var usdRate: String = (JSONObject(json).getJSONObject("bpi").getJSONObject("USD")["rate"] as String).toString()
val usdRateN1: String = usdRate.replace(",", "")
val sastoshi: Double = 0.00000001
var antalSatoshi = sastoshi * ddx.text.toString().toDouble()
var FinalUsdCount = (usdRateN1.toDouble() * antalSatoshi )
Math.round(FinalUsdCount)

Is there a more efficient way to reverse a integer number (both positive and negative) in SCALA?

I am making a program in SCALA that takes a integer number and reverses it. For example, an input of 30 returns an output of 3. This program must also work for negative numbers, For instance, an input of -89 returns an output of -98. Also, if in the reversal the first digit is 0, it should be truncated (30 to 3). This is the code I have written.
import io.StdIn._
val twoDigitNumber : Int = takeInput()
println("The reversal is " + reverse(twoDigitNumber))
//define a function name reverse to handle the actual reverse process for -ve and +ve numbers
def reverse(x: Integer): Integer = {
//4 possibilities: +ve, 1st digit 0; -ve, 1st digit zero; -ve, 1st digit not zero; +ve, 1st digit not zero
if (x> 0 && x.toString.reverse.charAt(0) == 0) {
x.toString.reverse.substring(1).toInt
} else if (x<0 && x.toString.substring(1).reverse.charAt(0) == 0) {
('-' + x.toString.substring(1).reverse.substring(1)).toInt
} else if (x<0 && x.toString.substring(1).reverse.charAt(0)!= 0) {
('-'+ x.toString.substring(1).reverse).toInt
} else {
x.toString.reverse.toInt
}
}
//reads an integer number
def takeInput() : Int ={
print("Enter a two-digit integer number: ")
readInt()
}
Is there a more efficient way to do this?
The shortest I found:
x.signum * x.abs.toString.reverse.toInt
It can be like below considering x is your integer input:
val reverseOutput = if (x>0) x.toString.reverse.toInt else -1* ((x * -1).toString.reverse.toInt)
def reverseANumber(n: Int): Int = {
def _reverseANumber(i: Int, i1: Int): Int = i match
case 0 => i1
case i =>
val n = i % 10
val n1 = n * math.pow(10, (((math.log10(i) + 1).toInt) - 1)).toInt
_reverseANumber(i / 10, i1 + n1)
_reverseANumber(n, 0)
}

Extract characters from string in R and save in different variables

I have the following dataset elections:
var1 <- c("125677", "255422", "475544", "333344", "233452")
var2 <- c("PRB", "PAN", "PR", "PV", "PJ")
var3 <- c("PCB/PTdoB/PCO/PRB", "PAN", "DEM/PR/PT/PSDB/PMDB/PV", "DEM/PR/PT/PSDB/PMDB/PV/PSTU/PSOL", "DEM/PJ")
elections <- cbind(var1, var2, var3)
Which looks like this:
var1 var2 var3
---------------
125677 PRB PCB/PTdoB/PCO/PRB
255422 PAN PAN
475544 PR DEM/PR/PT/PSDB/PMDB/PV
333344 PV DEM/PR/PT/PSDB/PMDB/PV/PSTU/PSOL
233452 PJ DEM/PJ
I want to disaggregate var3in eight additional variables, var4 to var11, that can be filled by the characters separated by / in var3. Therefore the result I want is this:
var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11
---------------------------------------------------------
125677 PRB PCB/PTdoB/PCO/PRB PCB PTdoB PCO PRB
255422 PAN PAN PAN
475544 PR DEM/PR/PT/PSDB/PMDB/PV DEM PR PT PSDB PMDB PV
333344 PV DEM/PR/PT/PSDB/PMDB/PV/PSTU/PSOL DEM PR PT PSDB PMDB PV PSTU PSOL
233452 PJ DEM/PJ DEM PJ
I was able to get a result close to the one I want with strsplit(elections$var3, '/'), but the problem is that this produces a list of objects. Therefore it works when there is only one element in var3, but it does not when there is more than one.
Any ideas?
A direct way would be to use read.csv (or read.table) on that variable (either before or after you add it to your existing dataset). Here, I've used read.csv which defaults with a fill = TRUE argument that will let you split the data the way you are expecting to.
Here's an example:
read.csv(text = elections[, "var3"], sep = "/", header = FALSE)
# V1 V2 V3 V4 V5 V6 V7 V8
# 1 PCB PTdoB PCO PRB
# 2 PAN
# 3 DEM PR PT PSDB PMDB PV
# 4 DEM PR PT PSDB PMDB PV PSTU PSOL
# 5 DEM PJ
Or, possibly (if your dataset is a data.frame):
read.csv(text = as.character(elections$var3), sep = "/", header = FALSE)
This approach is essentially what is taken with concat.split from my "splitstackshape" package, though it does a little bit more checking and will conveniently combine the output back into the original dataset.
Assuming now "elections" is a data.frame, usage would be:
library(splitstackshape)
concat.split(elections, "var3", "/", drop = TRUE)
# var1 var2 var3_1 var3_2 var3_3 var3_4 var3_5 var3_6 var3_7 var3_8
# 1 125677 PRB PCB PTdoB PCO PRB
# 2 255422 PAN PAN
# 3 475544 PR DEM PR PT PSDB PMDB PV
# 4 333344 PV DEM PR PT PSDB PMDB PV PSTU PSOL
# 5 233452 PJ DEM PJ
Update
Ultimately, however, read.csv is somewhat slow (so by extension, the concat.split approach would be slow). The approach I'm working on for a revision of the function is along the following lines until I come up with something better:
myMat <- function(inVec, sep) {
if (!is.character(inVec)) inVec <- as.character(inVec)
nCols <- max(vapply(gregexpr(sep, inVec, fixed = TRUE), length, 1L)) + 1
M <- matrix("", ncol = nCols, nrow = length(inVec))
Spl <- strsplit(inVec, sep, fixed = TRUE)
Len <- vapply(Spl, length, 1L)
Ind <- cbind(rep(seq_along(Len), Len), sequence(Len))
M[Ind] <- unlist(Spl)
M
}
Some benchmarks
Sample data:
var1 <- c("125677", "255422", "475544", "333344", "233452")
var2 <- c("PRB", "PAN", "PR", "PV", "PJ")
var3 <- c("PCB/PTdoB/PCO/PRB", "PAN", "DEM/PR/PT/PSDB/PMDB/PV", "DEM/PR/PT/PSDB/PMDB/PV/PSTU/PSOL", "DEM/PJ")
elections <- data.frame(var1, var2, var3)
Functions to evaluate:
fun1 <- function() myMat(elections$var3, "/")
fun2 <- function() read.csv(text = as.character(elections$var3), sep = "/", header = FALSE)
The results:
microbenchmark(fun1(), fun2())
# Unit: microseconds
# expr min lq median uq max neval
# fun1() 159.936 175.5445 193.291 244.6075 566.188 100
# fun2() 974.151 1017.1280 1070.796 1690.0100 2146.724 100
BIGGER data (but still not very big):
elections <- do.call(rbind, replicate(5000, elections, simplify = FALSE))
dim(elections)
# [1] 25000 3
microbenchmark(fun1(), fun2(), times = 10)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1() 195.1358 211.8841 232.1093 287.560 324.6918 10
# fun2() 2764.8115 3524.7989 3626.1480 3639.303 3728.2099 10
I run out of patience waiting for one million rows with fun2(), but for fun1(), it takes about 19 seconds, which is OK, but not something I'm totally happy with.

Find non-unique characters in a given string in O(n) time with constant space i.e with no extra auxiliary array

Given a string s containing only lower case alphabets (a - z), find (i.e print) the characters that are repeated.
For ex, if string s = "aabcacdddec"
Output: a c d
3 approaches to this problem exists:
[brute force] Check every char of string (i.e s[i] with every other char and print if both are same)
Time complexity: O(n^2)
Space complexity: O(1)
[sort and then compare adjacent elements] After sorting (in O(n log(n) time), traverse the string and check if s[i] ans s[i + 1] are equal
Time complexity: O(n logn) + O(n) = O(n logn)
Space complexity: O(1)
[store the character count in an array] Create an array of size 26 (to keep track of a - z) and for every s[i], increment value stored at index = s[i] - 26 in the array. Finally traverse the array and print all elements (i.e 'a' + i) with value greater than 1
Time complexity: O(n)
Space complexity: O(1) but we have a separate array for storing the frequency of each element.
Is there a O(n) approach that DOES NOT use any array/hash table/map (etc)?
HINT: Use BIT Vectors
This is the element distinctness problem, so generally speaking - no there is no way to solve it in O(n) without extra space.
However, if you regard the alphabet as constant size (a-z characters only is pretty constant) you can either create a bitset of these characters, in O(1) space [ it is constant!] or check for each character in O(n) if it repeats more than once, it will be O(constant*n), which is still in O(n).
Pseudo code for 1st solution:
bit seen[] = new bit[SIZE_OF_ALPHABET] //contant!
bit printed[] = new bit[SIZE_OF_ALPHABET] //so is this!
for each i in seen.length: //init:
seen[i] = 0
printed[i] = 0
for each character c in string: //traverse the string:
i = intValue(c)
//already seen it and didn't print it? print it now!
if seen[i] == 1 and printed[i] == 0:
print c
printed[i] = 1
else:
seen[i] = 1
Pseudo code for 2nd solution:
for each character c from a-z: //constant number of repeats is O(1)
count = 0
for each character x in the string: //O(n)
if x==c:
count += 1
if count > 1
print count
Implementation in Java
public static void findDuplicate(String str) {
int checker = 0;
char c = 'a';
for (int i = 0; i < str.length(); ++i) {
int val = str.charAt(i) - c;
if ((checker & (1 << val)) > 0) {
System.out.println((char)(c+val));
}else{
checker |= (1 << val);
}
}
}
Uses as int as storage and performs bit wise operator to find the duplicates.
it is in O(n) .. explanation follows
Input as "abddc"
i==0
STEP #1 : val = 98 - 98 (0) str.charAt(0) is a and conversion char to int is 98 ( ascii of 'a')
STEP #2 : 1 << val equal to ( 1 << 0 ) equal to 1 finally 1 & 0 is 0
STEP #3 : checker = 0 | ( 1 << 0) equal to 0 | 1 equal to 1 checker is 1
i==1
STEP #1 : val = 99 - 98 (1) str.charAt(1) is b and conversion char to int is 99 ( ascii of 'b')
STEP #2 : 1 << val equal to ( 1 << 1 ) equal to 2 finally 1 & 2 is 0
STEP #3 : checker = 2 | ( 1 << 1) equal to 2 | 1 equal to 2 finally checker is 2
i==2
STEP #1 : val = 101 - 98 (3) str.charAt(2) is d and conversion char to int is 101 ( ascii of 'd')
STEP #2 : 1 << val equal to ( 1 << 3 ) equal to 8 finally 2 & 8 is 0
STEP #3 : checker = 2 | ( 1 << 3) equal to 2 | 8 equal to 8 checker is 8
i==3
STEP #1 : val = 101 - 98 (3) str.charAt(3) is d and conversion char to int is 101 ( ascii of 'd')
STEP #2 : 1 << val equal to ( 1 << 3 ) equal to 8 finally 8 & 8 is 8
Now print 'd' since the value > 0
You can also use the Bit Vector, depends upon the language it would space efficient. In java i would prefer to use int for this fixed ( just 26) constant case
The size of the character set is a constant, so you could scan the input 26 times. All you need is a counter to store the number of times you've seen the character corresponding to the current iteration. At the end of each iteration, print that character if your counter is greater than 1.
It's O(n) in runtime and O(1) in auxiliary space.
Implementation in C# (recursive solution)
static void getNonUniqueElements(string s, string nonUnique)
{
if (s.Count() > 0)
{
char ch = s[0];
s = s.Substring(1);
if (s.LastIndexOf(ch) > 0)
{
if (nonUnique.LastIndexOf(ch) < 0)
nonUnique += ch;
}
getNonUniqueElements(s, nonUnique);
}
else
{
Console.WriteLine(nonUnique);
return;
}
}
static void Main(string[] args)
{
getNonUniqueElements("aabcacdddec", "");
Console.ReadKey();
}

match check in matlab

i have strings like these:
s{1,2} = 'string';
s{2,2} = 'string2';
and in workspace structure like this
U.W.string = [2 2.5 3]
I want to check (in loop) s{1,2} or s{2,2} or s{i,2} matches any structure with the same name. If so, assign values from this structure to some variable var(i). How can it be done?
Use isfields to check, if a string is the name of a field in a struct. Then use the syntax struct.(name), where name is a string to access the field. Your code might look something like:
test = struct('hello', 'world', 'count', 42, 'mean', 10);
fields = {'test', 'count';
'hello', 'text';
'more', 'less'};
values = {pi, 'dummy', -1};
for row = 1 : size(fields, 1)
for column = 1 : size(fields, 2)
if isfield(test, fields{row, column})
test.(fields{row, column}) = values{row};
end
end
end
This converts the initial struct
test =
hello: 'world'
count: 42
mean: 10
to this one
test =
hello: 'dummy'
count: 3.1416
mean: 10
A shorter implementation is achieved by removing the inner loop and giving a cell-array to isfields:
for row = 1 : size(fields, 1)
%# Note the parenthesis instead of curly braces in the next statement.
match = isfield(test, fields(row, :));
if any(match)
test.(fields{row, match}) = values{row};
end
end
Use isfield(structName,fieldName). This should do the trick:
strings{1,1} = 'foo';
strings{1,2} = 'bar';
strings{1, 3} = 'foobar';
U.W.foo = 1;
U.W.foobar = 5;
for idx = 1:length(strings)
if(isfield(U.W,strings{1,idx}))
expression = sprintf('outvar(idx) = U.W.%s',strings{1,idx});
eval(expression);
end
end

Resources