I want to split a number using regex. I have a number like xyz (x and y are single digits, z can be a 2 or three digit number), for example 001 or 103 or 112. I want to split it into separate numbers. This can be done, if I'm not wrong by doing split("",3); This will split the number (saved as string, but I don't think it makes difference in this case) 103 in an array with values 1,0,3.
Since here it's easy,the fact is that the last number z may be a 2 or 3 digit number.
So I could have 1034, 0001, 1011 so on. And I have to split it respectively into [1,0,34] [0,0,01] [1,0,11]
How can I do that?
Thanks
Sergiu
var regex:RegExp = /(\d)(\d)(\d+)/;
var n:Number = 1234;
var res:Array = regex.exec(n.toString()) as Array;
trace(res.join("\n"); /** Traces:
*
* 1234
* 1
* 2
* 34
*
* The first 1234 is the whole matched string
* and the rest are the three (captured) groups.
*/
Found the solution, I was going the hard way...it was just possible to use substr to substract the charcaters I want and the put them in an array.
Related
I would like to extract integers from strings from a cell array in Matlab. Each string contains 1 or 2 integers formatted as shown below. Each number can be one or two digits. I would like to convert each string to a 1x2 array. If there is only one number in the string, the second column should be -1. If there are two numbers then the first entry should be the first number, and the second entry should be the second number.
'[1, 2]'
'[3]'
'[10, 3]'
'[1, 12]'
'[11, 12]'
Thank you very much!
I have tried a few different methods that did not work out. I think that I need to use regex and am having difficulty finding the proper expression.
You can use str2num to convert well formatted chars (which you appear to have) to the correct arrays/scalars. Then simply pad from the end+1 element to the 2nd element (note this is nothing in the case there's already two elements) with the value -1.
This is most clearly done in a small loop, see the comments for details:
% Set up the input
c = { ...
'[1, 2]'
'[3]'
'[10, 3]'
'[1, 12]'
'[11, 12]'
};
n = cell(size(c)); % Initialise output
for ii = 1:numel(n) % Loop over chars in 'c'
n{ii} = str2num(c{ii}); % convert char to numeric array
n{ii}(end+1:2) = -1; % Extend (if needed) to 2 elements = -1
end
% (Optional) Convert from a cell to an Nx2 array
n = cell2mat(n);
If you really wanted to use regex, you could replace the loop part with something similar:
n = regexp( c, '\d{1,2}', 'match' ); % Match between one and two digits
for ii = 1:numel(n)
n{ii} = str2double(n{ii}); % Convert cellstr of chars to arrays
n{ii}(end+1:2) = -1; % Pad to be at least 2 elements
end
But there are lots of ways to do this without touching regex, for example you could erase the square brackets, split on a comma, and pad with -1 according to whether or not there's a comma in each row. Wrap it all in a much harder to read (vs a loop) cellfun and ta-dah you get a one-liner:
n = cellfun( #(x) [str2double( strsplit( erase(x,{'[',']'}), ',' ) ), -1*ones(1,1-nnz(x==','))], c, 'uni', 0 );
I'd recommend one of the loops for ease of reading and debugging.
I'm currently writing a validator where I need to check the formats of floats. My code reads in a format of (x,y) where x is the total possible digits in the float and y is the maximum digits out of x that can be after the decimal point. Apologies if this question has already been answered before, but I wasn't able to find anything similar.
For example, given a format of (5,3):
Valid values
55555
555.33
55.333
5555.3
.333
Invalid values
55555.5
555555
5.5555
.55555
This is my first time working with regex so if you guys have any tutorials that you recommend, please send it my way!
You can use a lookahead to ensure both conditions, like
^(?=(?:\.?\d){1,5}$)\d*(?:\.\d{1,3})?$
^ match from the start of the string
(?=(?:\.?\d){1,5}$) check for the presence of 1 up to 5 digits to the end of the string - not caring to much about the correct number of dots
\d* match any number of digits
(?:\.\d{1,3})? match up to 3 decimal places
$ ensure end of the string
See https://regex101.com/r/lrP56w/1
Assuming JS you can try
function validate(value, total, dec) {
let totalRegex = new RegExp(`\\d{0,${total}}$`);
let decimalRegex = new RegExp(`\\.\\d{0,${dec}}$`);
return totalRegex.test(value.replace(".","")) && (!(/\./.test(value)) || decimalRegex.test(value));
}
console.log(validate("555.55", 5, 2));
console.log(validate("55.555", 5, 2));
console.log(validate("5.5", 5, 2));
console.log(validate("55555", 5, 2));
console.log(validate("5.5555", 5, 2));
The task is to justify text within a certain width.
user inputs: Hello my name is Harrry. This is a sample text input that nobody
will enter.
output: What text width do you want?
user inputs: 15
output: |Hello my name|
|is Harrry. This|
|is a sample|
|text that|
|nobody will|
|enter. |
Basically, the line has to be 15 spaces wide including blank spaces. Also, if the next word in the line cant fit into 15, it will skip entirely. If there are multiple words in a line, it will try to distribute the spaces evenly between each word. See the line that says "Is a sample" for example.
I created a vector using getline(...) and all that and the entire text is saved in a vector. However, I'm kind of stuck on moving forward. I tried using multiple for loops, but I just cant seem to skip lines or even out the spacing at all.
Again, not looking or expecting anyone to solve this, but I'd appreciate it if you could guide me into the right direction in terms of logic/algorithm i should think about.
You should consider this Dynamic programming solution.
Split text into “good” lines
Since we don't know where we need to break the line for good justification, we start guessing where the break to be done to the paragraph. (That is we guess to determine whether we should break between two words and make the second word as start of the next line).
You notice something? We brutefore!
And note that if we can't find a word small enought to fit in the remaining space in the current line, we insert spaces inbetween the words in the current line. So, the space in the current line depends on the words that might go into the next or previous line. That's Dependency!
You are bruteforcing and you have dependency,there comes the DP!
Now lets define a state to identify the position on our path to solve this problem.
State: [i : j] ,which denotes line of words from ith word to jth word in the original sequence of words given as input.
Now, that you have state for the problem let us try to define how these states are related.
Since all our sub-problem states are just a pile of words, we can't just compare the words in each state and determine which one is better. Here better delineates to the use of line's width to hold maximum character and minimum spaces between the words in the particular line. So, we define a parameter, that would measure the goodness of the list of words from ith to jth words to make a line. (recall our definition of subproblem state). This is basically evaluating each of our subproblem state.
A simple comparison factor would be :
Define badness(i, j) for line of words[i : j].
For example,
Infinity if total length > page width,
else (page width − total length of words in current line)3
To make things even simple consider only suffix of the given text and apply this algorithm. This would reduce the DP table size from N*N to N.
So, For finishing lets make it clear what we want in DP terms,
subproblem = min. badness for suffix words[i :]
=⇒ No.of subproblems = Θ(n) where n = no of words
guessing = where to end first line, say i : j
=⇒ no. of choices for j = n − i = O(n)
recurrence relation between the subproblem:
• DP[i] = min(badness (i, j) + DP[j] for j in range (i + 1, n + 1))
• DP[n] = 0
=⇒ time per subproblem = Θ(n)
so, total time = Θ(n^2).
Also, I'll leave it to you how insert spaces between words after determining the words in each line.
Logic would be:
1) Put words in array
2) Loop though array of words
3) Count the number of chars in each word, and check until they are the text width or less (skip if more than textwidth). Remember the number of words that make up the total before going over 15 (example remember it took 3 words to get 9 characters, leaving space for 6 spaces)
4) Divide the number of spaces required by (number of words - 1)
5) Write those words, writing the same number of spaces each time.
Should give the desired effect I hope.
You obviously have some idea how to solve this, as you have already produced the sample output.
Perhaps re-solve your original problem writing down in words what you do in each step....
e.g.
Print text asking for sentence.
Take input
Split input into words.
Print text asking for width.
...
If you are stuck at any level, then expand the details into sub-steps.
I would look to separate the problem of working out a sequence of words which will fit onto a line.
Then how many spaces to add between each of the words.
Below is an example for printing one line after you find how many words to print and what is the starting word of the line.
std::cout << "|";
numOfSpaces = lineWidth - numOfCharsUsedByWords;
/*
* If we have three words |word1 word2 word3| in a line
* ideally the spaces to print between then are 1 less than the words
*/
int spaceChunks = numOfWordsInLine - 1;
/*
* Print the words from starting point to num of words
* you can print in a line
*/
for (j = 0; j < numOfWordsInLine; ++j) {
/*
* Calculation for the number of spaces to print
* after every word
*/
int spacesToPrint = 0;
if (spaceChunks <= 1) {
/*
* if one/two words then one
* chunk of spaces between so fill then up
*/
spacesToPrint = numOfSpaces;
} else {
/*
* Here its just segmenting a number into chunks
* example: segment 7 into 3 parts, will become 3 + 2 + 2
* 7 to 3 = (7%3) + (7/3) = 1 + 2 = 3
* 4 to 2 = (4%2) + (4/2) = 0 + 2 = 2
* 2 to 1 = (2%1) + (2/1) = 0 + 2 = 2
*/
spacesToPrint = (numOfSpaces % spaceChunks) + (numOfSpaces / spaceChunks);
}
numOfSpaces -= spacesToPrint;
spaceChunks--;
cout << words[j + lineStartIdx];
for (int space = 0; space < spacesToPrint; space++) {
std::cout << " ";
}
}
std::cout << "|" << std::endl;
Hope this code helps. Also you need to consider what happens if you set width less then the max word size.
Drazil is playing a math game with Varda.
Let's define for positive integer x as a product of factorials of its
digits. For example, f(135) = 1! * 3! * 5! = 720.
First, they choose a decimal number a consisting of n digits that
contains at least one digit larger than 1. This number may possibly
start with leading zeroes. Then they should find maximum positive
number x satisfying following two conditions:
x doesn't contain neither digit 0 nor digit 1.
= f(x) = f(a)
Help friends find such number.
Input The first line contains an integer n (1 ≤ n ≤ 15) — the number
of digits in a.
The second line contains n digits of a. There is at least one digit in
a that is larger than 1. Number a may possibly contain leading zeroes.
Output Output a maximum possible integer satisfying the conditions
above. There should be no zeroes and ones in this number decimal
representation.
Examples
input
4
1234
output
33222
input
3
555
output
555
Here is the solution,
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
int main()
{
map<char, string> mp;
mp['0'] = mp['1'] = "";
mp['2'] = "2";
mp['3'] = "3";
mp['4'] = "223";
mp['5'] = "5";
mp['6'] = "35";
mp['7'] = "7";
mp['8'] = "2227";
mp['9'] = "2337";
int n;
string str;
cin>>n>>str;
string res;
for(int i = 0; i < str.size(); ++i)
res += mp[str[i]];
sort(res.rbegin(), res.rend());
cout<<res;
return 0;
}
I'd like if someone explains the reason why were the digits transformed into other form of digits rather than just with some way to compute the number with..sadly brute force would give a TLE(Time limit exceeded) in this question cause of the 15 digit thing so that's a big number to brute force to,so I kindly hope that someone can explain the "proof" below, cause idk what theory says that these numbers can be transformed to those numbers for example 4 to 223 and stuff.
Thanks in advance.
Picture: What the proof says
The theory behind these transformations is the following (Ill use 4 as an example):
4! = 3! * 2! * 2!
A longer sequence of digits will always produce a larger number than a shorter sequence (at least for positive integers). Thus this code produces a longer sequence where possible. With the above example we get:
4! = 3! * 4
We can't reduce the 3! any further, since 3 is a prime. 4 on the other hand is simply 2²:
4 = 2² = 2! * 2!
Thus we have found the optimal replacement for 4 in the number-sequence as "322". This can be done for all numbers, but prime-numbers aren't factorisable and will thus always be the best replacement available for them self.
And thanks to the fact that we're using prime factorization we also know that we have the only (and longest possible) string of digits that can replace a certain digit.
In Matlab, let's say that I have the following string:
mystring = 'sdfkdsgoeskjgk elkr jtk34s ;3k54352642 643l j3kf p35j535';
And I want to extract all the digits in it to a vector such that each digit is standing by its own, so the output should be like:
output = [3 4 3 5 4 3 5 2 6 4 2....]
I tried to do it using this code and regex:
mystring = 'sdfkdsgoeskjgk elkr jtk34s ;3k54352642 643l j3kf p35j535';
digits = regexp(mystring, '[0-9]');
disp(digits);
But it gives me some weird 4-combined digits instead of what I need.
By default, the output of regexp is in the index of the first character in each match which is why the numbers aren't the same as the digits in your string. You'll want to use the output of regexp to then index into the initial string to get the digits themselves
digits = mystring(regexp(mystring, '[0-9]'));
You will still need to convert these from characters to numbers so you can subtract off '0' to do this conversion
digits = mystring(regexp(mystring, '[0-9]')) - '0';
Alternately, you could specify the 'match' input to regexp to return the actual matching string itself. This will return a cell array which we can then convert to an array of numbers using str2double
digits = str2double(regexp(mystring, '[0-9]', 'match'))
I use transposing instead of any other existing function to convert a string into an array.
mystring = 'sdfkdsgoeskjgk elkr jtk34s ;3k54352642 643l j3kf p35j535';
digits = regexp(mystring, '[0-9]');
array = double(mystring(digits)')'-48; % array of doubles
disp(array);