nlopt_add_equality_constraint doesn't work - nlopt

I write a program,
to minimize:
f = x^2 + y^2
constrain:
c: x-1 < 0
ceq: x+y-5=0
I got answer:
x = 0.12219
y = 5.678
which is not satisfy ceq.
I don't know how to fix it.
My complete source code is here
main function is as follow:
int main()
{
nlopt_opt opt;
opt = nlopt_create(NLOPT_LD_MMA, 2); /* algorithm and dimensionality */
nlopt_set_min_objective(opt, myfunc, NULL);
nlopt_add_equality_constraint(opt, ceq1, NULL, 1e-8);
nlopt_add_inequality_constraint(opt, c1, NULL, 1e-8);
nlopt_set_xtol_rel(opt, 1e-4);
double x[2] = { 1.234, 5.678 }; /* some initial guess */
double minf; /* the minimum objective value, upon return */
if (nlopt_optimize(opt, x, &minf) < 0) {
printf("nlopt failed!\n");
}
else {
printf("found minimum at f(%g,%g) = %0.10g\n", x[0], x[1], minf);
}
nlopt_destroy(opt);
return 0;
}
update!!!!!
After reading the document, I found the algorithm "MMA" doesn't support "equal constraint."
To replace "MMA" with "SLSQP" might solve this problem.

Related

How to fit/clip an axis aligned bounding box around a portion of a triangle

I have looked and looked and cannot find any resources on. I want to clip an axis aligned bounding box against a triangle in a way that creates a new tight fitting axis aligned bounding box around or in the triangle (I have seen the reverse a lot, a triangle clipped against an axis alinged bounding, but never seen the reverse case). I tried computing the clipped tiangle then building a bounding box from it. But it is grossly inefficent and I don't think my code is correct. Does anyone know how to clip a bounding box against a triangle efficently?
Here is pictures describing what I currently do
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef float f32;
typedef double f64;
struct Point
{
union
{
f32 a[3];
struct
{
f32 x;
f32 y;
f32 z;
};
};
};
struct BoundingBox3
{
Point m_vMin = {FLT_MAX,FLT_MAX,FLT_MAX};
Point m_vMax = {-FLT_MAX,-FLT_MAX,-FLT_MAX};
};
inline
s8 Classify( s8 sign, u8 axis, const Point *c_v, const Point *p_v )
{
const f64 d = sign * ( p_v->a[axis] - c_v->a[axis] );
if ( d > EPSILON )
{
return 1;
}
else if ( d < -EPSILON )
{
return -1;
}
return 0;
}
#define POINT_BUFFER_SIZE 9
inline
void Clip3D_plane( Point *pVerts, s8 sign, u8 axis, u8 *pdwNumVerts, const Point *pPointOnPlane )
{
u8 dwNumVerts = ( *pdwNumVerts );
if ( dwNumVerts == 0 )
{
return;
}
else if ( dwNumVerts == 1 )
{
*pdwNumVerts = 0;
return;
}
Point vNewVerts[POINT_BUFFER_SIZE];
u8 k = 0;
bool b = true; // polygon is fully located on clipping plane
Point v1 = pVerts[dwNumVerts - 1];
s8 d1 = Classify( sign, axis, pPointOnPlane, &v1 );
for ( u8 j = 0; j < dwNumVerts; ++j )
{
const Point &v2 = pVerts[j];
s8 d2 = Classify( sign, axis, pPointOnPlane, &v2 );
if ( d2 != 0 )
{
b = false;
if ( ( 0x80 & ( d2 ^ d1 ) ) != 0 ) //if signs differ
{
const f32 fAlpha = ( v2.a[axis] - pPointOnPlane->a[axis] ) / ( v2.a[axis] - v1.a[axis] );
Point_Lerp( &v2, &v1, fAlpha, &vNewVerts[k++] );
}
else if ( d1 == 0 && ( k == 0 || !Point_Equals( &vNewVerts[k - 1], &v1 ) ) )
{
vNewVerts[k++] = v1;
}
if ( d2 > 0 )
{
vNewVerts[k++] = v2;
}
}
else
{
if ( d1 != 0 )
{
vNewVerts[k++] = v2;
}
}
v1 = v2;
d1 = d2;
}
if ( b )
{
return;
}
*pdwNumVerts = k;
for ( u8 j = 0; j < k; ++j )
{
pVerts[j] = vNewVerts[j];
}
}
inline void BoundingBox_Append( BoundingBox3 *pBB, const Point *pvPoint )
{
pBB->m_vMin.x = min( pBB->m_vMin.x, pvPoint->x );
pBB->m_vMin.y = min( pBB->m_vMin.y, pvPoint->y );
pBB->m_vMin.z = min( pBB->m_vMin.z, pvPoint->z );
pBB->m_vMax.x = max( pBB->m_vMax.x, pvPoint->x );
pBB->m_vMax.y = max( pBB->m_vMax.y, pvPoint->y );
pBB->m_vMax.z = max( pBB->m_vMax.z, pvPoint->z );
}
void BoundingBox_ClipAndAppendTri( BoundingBox3 *pBB3, Point *pVerts, u8 *phwNumVerts, const BoundingBox3 *pClipBox )
{
for ( u8 axis = 0; axis < 3; ++axis )
{
Clip3D_plane( pVerts, 1, axis, phwNumVerts, &pClipBox->m_vMin );
Clip3D_plane( pVerts, -1, axis, phwNumVerts, &pClipBox->m_vMax );
}
for ( u8 vert = 0; vert < *phwNumVerts; ++vert )
{
BoundingBox_Append( pBB3, &pVerts[vert] );
}
}
In general you can't escape computing intersection points between the sides of the triangle and those of the box. To get a correct result, you need to compute the intersection of the two shapes, for instance using the Sutherland-Hodgman algorithm, that you can specialize for the case of a triangle and a rectangle. If I am right, in the worst case you get an heptagon.
Then getting the AABB is no big deal.
Alternatively, you can implement a line-segment clipping algorithm against a poygonal (triangular or rectangular) window. A specialization to an AA window is the Cohen-Sutherland algorithm. Then clip all triangle sides against the rectangle and all rectangle sides against the triangle.

issues with Optimizing Speed and Strings

How can I optimize the processing of strings?
Your problem is you are making n copies of t and concatenating them. This is a simple approach, but quite expensive - it turns what could be an O(n) solution into an O(n2) one.
Instead, just check each char of s:
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != t.charAt(i % t.length())) {
return -1:
}
}
Do not make new strings, but use String.regionMatches.
Use String.length and modulo % == 0.
The smallest substring of t can be done using the same method.
Coding:
new String(string) ist never needed.
String += is slow. Better use StringBuilder.
No code to not spoil your coding.
Just a remark:
in general working with char[] is much faster than working with String.
(but nowhere near as convenient)
And make your variables final when they are final.
(it makes no difference to performance, but aids understanding)
Anyway, this might do it:
import java.util.Arrays;
class Result {
public static int findSmallestDivisor(final String s, final String t) {
final int lenS = s.length();
final int lenT = t.length();
/*
* Get Length & Chars of shortest & longest Strings...
*/
final int lenShort;
final int lenLong;
final char[] charsShort;
final char[] charsLong;
if (lenS < lenT) {
lenShort = lenS; charsShort = s.toCharArray();
lenLong = lenT; charsLong = t.toCharArray();
} else {
lenShort = lenT; charsShort = t.toCharArray();
lenLong = lenS; charsLong = s.toCharArray();
}
/*
* Get the Factor & exit if there's a remainder...
*/
final int factor = lenLong / lenShort;
final int factorRem = lenLong % lenShort;
if (factorRem != 0) {
return -1;
}
/*
* Try all possible divisors...
*/
for (int d=1; d <= lenShort; d++) {
final int n = lenShort / d;
final int nRem = lenShort % d;
if (nRem != 0) {
continue;
}
final char[] dChars = Arrays.copyOf(charsShort, d);
final char[] dCharsMultipliedShort = multiplyChars(dChars, n);
final char[] dCharsMultipliedLong = multiplyChars(dCharsMultipliedShort, factor);
if (Arrays.equals(charsShort, dCharsMultipliedShort)
&& Arrays.equals(charsLong, dCharsMultipliedLong )) {
return d;
}
}
return -1;
}
private static char[] multiplyChars(final char[] a, final int n) {
// if (n == 0) { // Necessary: otherwise ArrayIndexOutOfBoundsException in getChars(...)
// return new char[] {}; // (n is never 0)
// }
if (n == 1) { // Optional: optimisation
return a;
}
final int aLength = a.length;
final char[] charsMultiplied = new char[aLength * n];
System.arraycopy(a, 0, charsMultiplied, 0, aLength); // Fill in 1st occurrence
/*
* Copy 1st occurrence to the remaining occurrences...
*/
for (int i = 1; i < n; i++) {
System.arraycopy(charsMultiplied, 0, charsMultiplied, i*aLength, aLength);
}
return charsMultiplied;
}
}

Find the largest string such that 'a', 'b', 'c' are not continuos

Q3:- We are given the maximum occurances of ‘a’, ‘b’ and ‘c’ in a string. We need to make the largest length string containing only ‘a’, ‘b’ and ‘c’ such that no three consecutive characters are same.
Ex:-
Input:- 3 3 3
Output:- abcabcabc
(There can be a lot of different outputs)
Input:- 5 5 3
Output:- aabbcaabbcabc
You could use this algorithm:
As a preprocessing step, associate each letter (a, b and c) with its corresponding maximum frequency, so you can sort these character-frequency pairs as you wish.
Start with an empty string and perform the following actions in a loop:
Sort the three letter-frequency pairs by decreasing frequency
Pick the first pair from the sorted list and check its frequency. If it is zero, return the string
If that selected character would violate the rule that the same character cannot repeat 3 times in a row, then pick the second pair from the sorted list instead and check its frequency. If it is zero, return the string
Add the selected character to the string, and decrease its frequency.
Repeat.
Here is an interactive implementation in JavaScript:
function largestSequence(freq) {
// Create a data structure the links a frequency with a letter (a, b or c)
let chars = [];
for (let i = 0; i < 3; i++) {
chars[i] = {
freq: freq[i],
chr: "abc"[i]
};
}
let s = "";
while (true) {
// Sort the three characters by decreasing frequency
chars.sort((a, b) => b.freq - a.freq);
let choice = chars[0]; // Choose the one with the highest frequency
if (choice.freq === 0) break; // If no more character is avaiable, exit
if (choice.chr + choice.chr === s.slice(-2)) {
// If this character would violate the rule, choose the
// second one from the sorted list:
choice = chars[1];
if (choice.freq === 0) break; // If that character is not available, exit
}
choice.freq--; // Use this character
s += choice.chr;
}
return s;
}
// I/O handling
let input = document.querySelector("input");
let output = document.querySelector("span");
input.oninput = function() {
let freq = (input.value.match(/\d+/g) || []).map(Number);
if (freq.length !== 3) {
output.textContent = "(Please enter three integers)";
} else {
output.textContent = largestSequence(freq);
}
};
input.oninput();
Frequencies for a, b, and c: <input value="3 3 3"><br>
Longest string: <span></span>
Working Simple Solution with PQ
class Node {
int count;
char c;
public Node(int count, char c) {
this.count = count;
this.c = c;
}
public void dec() {
this.count--;
}
}
public String solution(int A, int B, int C) {
PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> b.count - a.count);
if (A>0)
queue.add(new Node(A, 'a'));
if (B>0)
queue.add(new Node(B, 'b'));
if (C>0)
queue.add(new Node(C, 'c'));
StringBuilder ans = new StringBuilder();
while (!queue.isEmpty()) {
Node max1 = queue.poll();
ans.append(max1.c); // a
max1.dec();
if (queue.size()>0){
Node max2 = queue.poll();
if (max1.count > max2.count) {
ans.append(max1.c); //aa
max1.dec();
ans.append(max2.c); //aab
max2.dec();
}
if (max2.count>0){
queue.add(max2); // add back if count not zero
}
} else {
if (max1.count>0){
ans.append(max1.c); //aa and return as queue size is 1
max1.dec();
return ans.toString();
}
}
if (max1.count>0){
queue.add(max1); // add back if count not zero
}
}
return ans.toString();
}
// C++ implementation
#include <bits/stdc++.h>
using namespace std;
bool compare(pair<int, char> a, pair<int, char> b) {
// Sorting according to decreasing frequencies
return a.first > b.first;
}
int main() {
int t;
cin>>t;
while(t--) {
// Making vector of pairs and mapping them with their characters v[0] is for "a", v[1] is for "b", v[2] is for "c"
vector<pair<int, char>> v(3);
cin>>v[0].first>>v[1].first>>v[2].first;
v[0].second = 'a';
v[1].second = 'b';
v[2].second = 'c';
string s;
int total = v[0].first + v[1].first + v[2].first;
while(1) {
string prev = s;
// sorting to bring the highest frequency element to front
sort(v.begin(), v.end(), compare);
if(v[0].first == 0)
break;
// when length of the string < 2
if(s.length() < 2) {
s += v[0].second;
v[0].first -= 1;
continue;
}
// when length of the string > 2
int len = s.length();
for(int i = 0; i < 3; ++i) {
if(v[i].first > 0 and (s[len - 1] != v[i].second or s[len - 2] != v[i].second)) {
s += v[i].second;
v[i].first -= 1;
break;
}
}
// check if the state has not changed from the previous state even after checking for "a", "b" and "c"
if(s.length() == prev.length())
break;
}
cout<<s<<"\n";
}
return 0;
}
You can do something similar using Priority Queue in C++. Adding my answer for someone looking for the answer in future.
int main() {
int a,b,c;
cin>>a>>b>>c;
priority_queue<pair<int,char>> pq;
pq.push({a,'a'});
pq.push({b,'b'});
pq.push({c,'c'});
string res="";
int x=5;
while(true){
auto p=pq.top(); pq.pop();
if(p.first==0){
break;
}
if(res.length()==0){
res+=string(min(p.first,2),p.second);
p.first-=min(p.first,2);
pq.push(p);
continue;
}
int len=res.length();
if(len>=1 && res[len-1]==p.second){
auto p2=pq.top();
pq.pop();
if(p2.first==0){
break;
}
res+=string(min(p2.first,2),p2.second);
p2.first-=min(p2.first,2);
pq.push(p2);
}else{
if(p.first==0){
break;
}
res+=string(min(p.first,2),p.second);
p.first-=min(p.first,2);
}
pq.push(p);
}
cout<<res<<endl;
}

In place string manipulation for character count

Given a string, do in place replacement of every character with it's immediate count.
eg: "aaabbbcc" - "a3b3c2"
"abab" - "a1b1a1b1"
You can do something like below
function getResult(input) {
if(!input) {
return ''; // if string is empty, return ''
}
if (input.length === 1) { // if string length is 1, return input + '1'
return input + '1'
}
var inputLength = input.length; // total length of the input string
var preChar = input[0]; // track previous character
var count = 1; // count of the previous character
for (var i = 1; i < inputLength; i++) {
if (preChar === input[i]) { // previous char and current char match
preChar = input[i]; // update prevChar with current char
count++; // count of prevChar is incremented
if (i + 1 < inputLength) { // not the end of the string
input = input.substr(0, i) + '#' + input.substr(i + 1); // update with dummy char '#' to maintain the length of the string, later will be removed
} else { // if it is the end of the string, update with count
input = input.substr(0, i) + count + input.substr(i + 1);
}
continue;
}
// if current char is not matched with prevChar
preChar = input[i]; // update the preChar with current char
// update the input with prevChar count and current char
input = input.substr(0, i) + count + input[i] + input.substr(i + 1);
inputLength++; // new count is added in the string, so total length of the string is increased by one
i++; // increment the i also because total length is increased
count = 1; // update the count with 1
if (i + 1 === inputLength) { // if it is last element
input = input.substr(0, i+1) + count + input.substr(i + 2);
}
}
input = input.replace(/\#/g, '') // remove dummy char '#' with ''
return input; // return the input
}
console.log("result for aaabbbcc is ", getResult('aaabbbcc'))
console.log("result for abab is ", getResult('abab'))
This answer assumes the OP uses ASCII
Analysis of the requirement of the the OP
Analysis of the bytes required:
When there is 1 repeat only, 2 bytes are needed.
When there are 2 repeats, 2 bytes are needed.
When there are 3, 2 bytes are needed.
When there are 9, 2 bytes.
When there are 99, 3 bytes.
When there are 999, 4 bytes.
When there are (2^64 - 1) repeats, only 20 bytes are needed.
As you can see, the bytes required to express the integer are log10(N)(at least 1) where N is the number of repeats.
Repeat-once
So, when there is only 1 repeat and there is no spare space, it has to keep iterating until
sequence that have more bytes than needed(have at least 3 repeats) to give it space
to reallocate when the end is reached
(In a string where most repeat at least twice or thrice and those who only repeat once are not gathered in one place, this is seldom required. This algorithm makes this assumption).
Then, the string will be modified backward to prevent any overwritten of data. This work because for each repeat-once sequence, it will take up double bytes to store them, so when the sequence at i will be written at 2i.
C++14 Code
#include <algorithm>
#include <cassert>
#include <utility>
#include <type_traits>
// Definition of helper functions for converting ints to string(raw and no need for format string).
template <class size_t, class UnsignedInt,
class = std::enable_if_t<std::is_unsigned<UnsignedInt>::value>>
size_t to_str_len(UnsignedInt i) noexcept
{
size_t cnt = 0;
do {
++cnt;
i /= 10;
} while (i > 0);
return cnt;
}
/*
* out should either points to the beginning of array or the last.
* step should be either 1 or -1.
*/
template <class RandomAccessIt, class UnsignedInt,
class = std::enable_if_t<std::is_unsigned<UnsignedInt>::value>>
auto uitos_impl(RandomAccessIt out, int step, UnsignedInt i) noexcept
{
do {
*out = static_cast<char>(i % 10) + 48;
out += step;
i /= 10;
} while (i > 0);
return out;
}
template <class BidirectionalIt>
void reverse_str(BidirectionalIt beg, BidirectionalIt end) noexcept
{
do {
std::iter_swap(beg++, --end);
} while (beg < end);
}
template <class RandomAccessIt, class UnsignedInt>
auto uitos(RandomAccessIt beg, UnsignedInt i) noexcept
{
auto ret = uitos_impl(beg, 1, i);
// Reverse the string to get the right order
reverse_str(beg, ret);
return ret;
}
template <class RanIt, class UnsignedInt>
auto r_uitos(RanIt last, UnsignedInt i) noexcept
{
return uitos_impl(last, -1, i);
}
template <class size_t, class RandomAccessIt>
size_t count_repeat(RandomAccessIt beg, RandomAccessIt end) noexcept
{
auto first = beg;
auto &val = *beg;
do {
++beg;
} while (beg != end && *beg == val);
return beg - first;
}
template <class size_t, class RandomAccessIt>
size_t r_count_repeat(RandomAccessIt last) noexcept
{
auto it = last;
auto &val = *it;
do {
--it;
} while (*it == val);
return last - it;
}
template <class string,
class size_type = typename string::size_type>
struct character_count
{
static_assert(std::is_unsigned<size_type>::value,
"size_type should be unsigned");
static_assert(!std::is_empty<size_type>::value,
"size_type should not be empty");
private:
using str_size_t = typename string::size_type;
using str_it = typename string::iterator;
static_assert(std::is_same<typename string::value_type, char>::value,
"Only support ASCII");
static_assert(sizeof(size_type) <= sizeof(str_size_t),
"size_type should not be bigger than typename string::size_type");
string str;
str_it in;
str_it out;
str_it end;
size_type len;
void cnt_repeat() noexcept
{
assert(in != end);
len = count_repeat<size_type>(in, str.end());
}
void advance_in() noexcept
{
assert(in != end);
in += len;
assert(in <= end);
}
void process_impl()
{
assert(in != end);
assert(out <= in);
// The main loop
do {
cnt_repeat();
if (len > 1 || out < in) {
*out = *in;
out = uitos(out + 1, len);
advance_in();
assert(out <= in);
} else {
auto first = find_enough_space();
auto deduced_first = write_backward();
assert(first == deduced_first);
}
} while (in != end);
}
auto find_enough_space()
{
assert(out == in);
auto first = in;
size_type bytes_required = 0;
do {
cnt_repeat();
advance_in();
bytes_required += to_str_len<size_type>(len) + 1;
if (size_type(in - first) >= bytes_required) {
out = first + bytes_required;
return first;
}
} while (in != str.end());
auto first_offset = first - str.begin();
// Hopefully this path won't be executed.
auto new_size = first_offset + bytes_required;
auto original_size = str.size();
assert(new_size > original_size);
str.resize(new_size);
first = str.begin() + first_offset;
out = str.end();
in = str.begin() + original_size;
end = str.begin() + original_size;
return first;
}
auto write_backward() noexcept
{
auto original_out = out--;
auto original_in = in--;
do {
len = r_count_repeat<size_type>(in);
out = r_uitos(out, len);
*out-- = *((in -= len) + 1);
} while (out != in);
auto ret = out + 1;
out = original_out;
in = original_in;
return ret;
}
public:
character_count(string &&arg):
str(std::move(arg)), in(str.begin()), out(str.begin()), end(str.end())
{}
character_count(const string &arg):
str(arg), in(str.begin()), out(str.begin()), end(str.end())
{}
/*
* ```str``` should not be empty and should not have non-visible character
*/
auto& process()
{
assert(!str.empty());
process_impl();
str.erase(out, str.end());
return *this;
}
auto& get_result() & noexcept
{
return str;
}
auto&& get_result() && noexcept
{
return std::move(str);
}
auto& get_result() const& noexcept
{
return str;
}
/*
* ```str``` should not be empty and should not have non-visible character
*/
auto& set_string(const string &arg) noexcept
{
str = arg;
in = str.begin();
out = str.begin();
end = str.end();
return *this;
}
/*
* ```str``` should not be empty and should not have non-visible character
*/
auto& set_string(string &&arg) noexcept
{
str = std::move(arg);
in = str.begin();
out = str.begin();
end = str.end();
return *this;
}
};
Assuming you're using Javascript, this is how I would do it. Just match all the groups with a regex and loop over them:
function charCount (str) {
const exp = /(\w)\1*/g
let matches = (str).match(exp)
let output = ''
matches.forEach(group => {
output += group[0] + group.length
})
return output
}
const str = 'abab'
const str2 = 'aaabbbcc'
console.log(charCount(str)) // a1b1a1b1
console.log(charCount(str2)) // a3b3c2

How to parse a string to an integer without library functions?

I was recently asked this question in an interview:
"How could you parse a string of the form '12345' into its integer representation 12345 without using any library functions, and regardless of language?"
I thought of two answers, but the interviewer said there was a third. Here are my two solutions:
Solution 1: Keep a dictionary which maps '1' => 1, '2' => 2, etc. Then parse the string one character at a time, look up the character in your dictionary, and multiply by place value. Sum the results.
Solution 2: Parse the string one character at a time and subtract '0' from each character. This will give you '1' - '0' = 0x1, '2' - '0' = 0x2, etc. Again, multiply by place value and sum the results.
Can anyone think of what a third solution might be?
Thanks.
I expect this is what the interviewer was after:
number = "12345"
value = 0
for digit in number: //Read most significant digit first
value = value * 10 + valueOf(digit)
This method uses far less operations than the method you outlined.
Parse the string in oposite order, use one of the two methods for parsing the single digits, multiply the accumulator by 10 then add the digit to the accumulator.
This way you don't have to calculate the place value. By multiplying the accumulator by ten every time you get the same result.
Artelius's answer is extremely concise and language independent, but for those looking for a more detailed answer with explanation as well as a C and Java implementation can check out this page:
http://www.programminginterview.com/content/strings
Scroll down (or search) to "Practice Question: Convert an ASCII encoded string into an integer."
// java version
public static int convert(String s){
if(s == null || s.length() == 0){
throw new InvalidParameterException();
}
int ret = 0;
boolean isNegtive = false;
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if( i == 0 && (c == '-')){
isNegtive = true;
continue;
}
if(c - '0' < 0 || c - '0' > 10){
throw new InvalidParameterException();
}
int tmp = c - '0';
ret *= 10;
ret += tmp;
}
return isNegtive ? (ret - ret * 2) : ret;
}
//unit test
#Test
public void testConvert() {
int v = StringToInt.convert("123");
assertEquals(v, 123);
v = StringToInt.convert("-123");
assertEquals(v, -123);
v = StringToInt.convert("0");
assertEquals(v, 0);
}
#Test(expected=InvalidParameterException.class)
public void testInvalidParameterException() {
StringToInt.convert("e123");
}
#Rule
public ExpectedException exception = ExpectedException.none();
#Test
public void testInvalidParameterException2() {
exception.expect(InvalidParameterException.class);
StringToInt.convert("-123r");
}
Keep a dictionary which maps all strings to their integer counterparts, up to some limit? Doesn't maybe make much sense, except that this probably is faster if the upper limit is small, e.g. two or three digits.
You could always try a binary search through a massive look up table of string representations!
No-one said anything about efficiency... :-)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int nod(long);
char * myitoa(long int n, char *s);
void main()
{
long int n;
char *s;
printf("Enter n");
scanf("%ld",&n);
s=myitoa(n,s);
puts(s);
}
int nod(long int n)
{
int m=0;
while(n>0)
{
n=n/10;
m++;
}
return m;
}
char * myitoa(long int n, char *s)
{
int d,i=0;
char cd;
s=(char*)malloc(nod(n));
while(n>0)
{
d=n%10;
cd=48+d;
s[i++]=cd;
n=n/10;
}
s[i]='\0';
strrev(s);
return s;
}
This is Complete program with all conditions positive, negative without using library
import java.util.Scanner;
public class StringToInt {
public static void main(String args[]) {
String inputString;
Scanner s = new Scanner(System.in);
inputString = s.nextLine();
if (!inputString.matches("([+-]?([0-9]*[.])?[0-9]+)")) {
System.out.println("error!!!");
} else {
Double result2 = getNumber(inputString);
System.out.println("result = " + result2);
}
}
public static Double getNumber(String number) {
Double result = 0.0;
Double beforeDecimal = 0.0;
Double afterDecimal = 0.0;
Double afterDecimalCount = 0.0;
int signBit = 1;
boolean flag = false;
int count = number.length();
if (number.charAt(0) == '-') {
signBit = -1;
flag = true;
} else if (number.charAt(0) == '+') {
flag = true;
}
for (int i = 0; i < count; i++) {
if (flag && i == 0) {
continue;
}
if (afterDecimalCount == 0.0) {
if (number.charAt(i) - '.' == 0) {
afterDecimalCount++;
} else {
beforeDecimal = beforeDecimal * 10 + (number.charAt(i) - '0');
}
} else {
afterDecimal = afterDecimal * 10 + number.charAt(i) - ('0');
afterDecimalCount = afterDecimalCount * 10;
}
}
if (afterDecimalCount != 0.0) {
afterDecimal = afterDecimal / afterDecimalCount;
result = beforeDecimal + afterDecimal;
} else {
result = beforeDecimal;
}
return result * signBit;
}
}

Resources