I'm trying to shift letters to the end of the word. Like the sample output I have in the image.
Using getchar and remove function, I was able to shift 1 letter.
mychar = GetChar(word, 1) 'Get the first character
word = word.Remove(0, 1) 'Remove the first character
input.Text = mychar
word = word & mychar
output.Text = word
This is my code for shifting 1 letter.
I.E. for the word 'Star Wars', it currently shifts 1 letter, and says 'tar WarsS'
How can I make this move 3 characters to the end? Like in the sample image.
intNumChars = input.text
output.text = mid(word,4,len(word)) & left(word,3)
I wanted it to be easy for you to read but you can set the intNumChars variable to the value in your text box and replace the 4 with intNumChars + 1 and the 3 with intNumChars.
The mid() function can return a section of text in the middle of a string mid(string,start,finish). The len() function returns the length of a string so that the code will work on texts that are different lengths. The left function returns characters from the left() of a string.
I hope this is of some help.
You could write a that as a sort of permute, which maps each char-index to a new place in the range [0, textLength[
In order to do that you'll have to write a custom modulus as the Mod operator is more a remainder than a modulus (from a mathematical point of view, regarding how negative are handled)
With that you just need to loop over your string indexes and map each one to it's "offsetted" value modulo the length of the text
' Can be made local to Shift method if needed
Function Modulus(dividend As Integer, divisor As Integer) As Integer
dividend = dividend Mod divisor
Return If(dividend < 0, dividend + divisor, dividend)
End Function
Function Shift(text As String, offset As Integer) As String
' validation omitted
Dim length = text.Length
Dim arr(length - 1) As Char
For i = 0 To length - 1
arr(Modulus(i + offset, length) Mod length) = text(i)
Next
Return new String(arr)
End Function
That way you can easily handle negative values or values greater than the length of the text.
Note, the same thing is possible with a StringBuilder instead of an array ; I'm not sure which one is "better"
Function Shift(text As String, offset As Integer) As String
Dim builder As New StringBuilder(text)
Dim length = text.Length
For i = 0 To length - 1
builder(Modulus(i + offset, length) Mod length) = text(i)
Next
Return builder.ToString
End Function
Using Gordon's code did the trick. The left function visual studio tried to create a stub of the function, so I used the fully qualified function name when calling it. But this worked perfectly.
intNumChars = shiftnumber.Text
output.Text = Mid(word, intNumChars + 1, Len(word)) & Microsoft.VisualBasic.Left(word, intNumChars)
n = 3
output.Text = Right(word, Len(word) - n) & Left(word, n)
Related
How do I read the first 1 to 2 integers of a string in a loop? I need to only parse the first integer or the second integer. For example, "8sdr" I only want to parse "8" and then for a "12sdr" I want to parse "12". I need this to be in a loop to be able to continuously parse only the first integers in a string. Thank you!
The following will return any given number of digits from the start of a string:
Function LeadingDigits(text As String, maxDigits As Integer) As String
Dim pos As Integer, c As String
Do Until pos >= maxDigits Or pos >= Len(text)
c = Mid$(text, pos + 1, 1)
If c < "0" Or c > "9" Then Exit Do
pos = pos + 1
Loop
LeadingDigits = Mid$(text, 1, pos)
End Function
Contrary to solutions that rely on IsNumeric() or Val(), this function does not get confused by strings that can be interpreted as numeric, but don't fall into the specification, such as
hexadecimal ("&habc" = 2748)
scientific notation ("3e4" = 30000)
+/- signs at the start of the string
decimal numbers ".5" = 0.5
Only decimal digits 0–9 at the start of the string are accepted.
The function returns a string, not a numeric type (like Integer) so that there can be a separate return value for "nothing found" (the empty string), and so that very long numbers can be returned that would not fit into a numeric data type.
If you need only up to two numbers that occur before a letter I would use RegEx for this:
Public Function FirstTwoNumbersFromStringBeforeLetter(ByVal textNumbers As String) As Long
Dim regEx
Set regEx = CreateObject("vbscript.regexp")
With regEx
.Global = True
.Pattern = "[a-z].*|\D"
FirstTwoNumbersFromStringBeforeLetter = Left(Val(.Replace(textNumbers, vbNullString)), 2)
End With
End Function
I'm using this query in vb.net
Raw_data = Alltext_line.Substring(Alltext_line.IndexOf("R|1"))
and I want to increase R|1 to R|2, R|3 and so on using for loop.
I tried it many ways but getting error
string to double is invalid
any help will be appreciated
You must first extract the number from the string. If the text part ("R") is always separated from the number part by a "|", you can easily separated the two with Split:
Dim Alltext_line = "R|1"
Dim parts = Alltext_line.Split("|"c)
parts is a string array. If this results in two parts, the string has the expected shape and we can try to convert the second part to a number, increase it and then re-create the string using the increased number
Dim n As Integer
If parts.Length = 2 AndAlso Integer.TryParse(parts(1), n) Then
Alltext_line = parts(0) & "|" & (n + 1)
End If
Note that the c in "|"c denotes a Char constant in VB.
An alternate solution that takes advantage of the String type defined as an Array of Chars.
I'm using string.Concat() to patch together the resulting IEnumerable(Of Char) and CInt() to convert the string to an Integer and sum 1 to its value.
Raw_data = "R|151"
Dim Result As String = Raw_data.Substring(0, 2) & (CInt(String.Concat(Raw_data.Skip(2))) + 1).ToString
This, of course, supposes that the source string is directly convertible to an Integer type.
If a value check is instead required, you can use Integer.TryParse() to perform the validation:
Dim ValuePart As String = Raw_data.Substring(2)
Dim Value As Integer = 0
If Integer.TryParse(ValuePart, Value) Then
Raw_data = Raw_data.Substring(0, 2) & (Value + 1).ToString
End If
If the left part can be variable (in size or content), the answer provided by Olivier Jacot-Descombes is covering this scenario already.
Sub IncrVal()
Dim s = "R|1"
For x% = 1 To 10
s = Regex.Replace(s, "[0-9]+", Function(m) Integer.Parse(m.Value) + 1)
Next
End Sub
How can I add an integer to another integer in vb.net?
This is what I need to do:
Given integer: 2187 ->
Converted integer: 2018
I need to add a 0 in between the first and second number, and drop the last digit. This will give me the year.
Here is the code that I have:
Protected Function GetYear(ByVal term As Integer) As Integer
Dim termYear As String = Convert.ToString(term)
termYear.Substring(0, 2)
termYear.Insert(1, "0")
Dim convertedYear As Integer
Int32.TryParse(termYear.ToString, convertedYear)
convertedYear = convertedYear / 10
Return convertedYear
End Function
In general strings are immutable. So you'd have to create a new string out of the addition of substrings. Check this possible solution.
Function GetYear(ByVal term As Integer) As Integer
Dim termYear As String = Convert.ToString(term, Globalization.CultureInfo.InvariantCulture)
Dim result As String = termYear.Substring(0, 1) + "0" + termYear.Substring(1, 2)
Return Int32.Parse(result)
End Function
Strings are immutable, when you do any changes with one of their method, you need to get the returned string.
termYear = termYear.Insert(1, "0")
This question deserves a math based solution. The below code specifies the zero insertion point relative to the number's right side instead of the left as stated in the problem statement. So for a 4 digit number the insertion point is 3 versus 2. It also allows you to change the insertion point.
Private Function GetYear(ByVal term As Integer, Optional zeroDigitPosition As Integer = 3) As Integer
If zeroDigitPosition > 0 Then
Dim divisor As Integer = 1
For i As Integer = 1 To zeroDigitPosition - 1
divisor *= 10
Next
Dim ret As Integer = term \ 10 ' drop one's place digit, remaining digits shift to right
Dim rightShiftedDigits As Integer = ret Mod divisor
Dim remainder As Integer = Math.DivRem(ret, divisor, rightShiftedDigits)
' shift the remainder to the left by divisor * 10
' (remember first right shift invplved \ 10) and add
' rightShiftedDigits to yield result
Return (remainder * divisor * 10) + rightShiftedDigits
Else
Throw New ArgumentOutOfRangeException("zeroDigitPosition must be greater then zero")
End If
End Function
I use vba in ms access,and found that ,if my parameter greater than 0x8000
less than 0x10000, the result is minus number
eg. Val("&H8000") = -32768 Val("&HFFFF")= -1
how can i get the unsigned number?
thanks!
There's a problem right here:
?TypeName(&HFFFF)
Integer
The Integer type is 16-bit, and 65,535 overflows it. This is probably overkill, but it was fun to write:
Function ConvertHex(ByVal value As String) As Double
If Left(value, 2) = "&H" Then
value = Right(value, Len(value) - 2)
End If
Dim result As Double
Dim i As Integer, j As Integer
For i = Len(value) To 1 Step -1
Dim digit As String
digit = Mid$(value, i, 1)
result = result + (16 ^ j) * Val("&H" & digit)
j = j + 1
Next
ConvertHex = result
End Function
This function iterates each digit starting from the right, computing its value and adding it to the result as it moves to the leftmost digit.
?ConvertHex("&H10")
16
?ConvertHex("&HFF")
255
?ConvertHex("&HFFFF")
65535
?ConvertHex("&HFFFFFFFFFFFFF")
281474976710655
UPDATE
As I suspected, there's a much better way to do this. Credits to #Jonbot for this one:
Function ConvertHex(ByVal value As String) As Currency
Dim result As Currency
result = CCur(value)
If result < 0 Then
'Add two times Int32.MaxValue and another 2 for the overflow
'Because the hex value is apparently parsed as a signed Int64/Int32
result = result + &H7FFFFFFF + &H7FFFFFFF + 2
End If
ConvertHex = result
End Function
Append an ampersand to the hex literal to force conversion to a 32bit integer:
Val("&HFFFF" & "&") == 65535
Val("&H8000&") == +32768
Don't use Val. Use one of the built-in conversion functions instead:
?CCur("&HFFFF")
65535
?CDbl("&HFFFF")
65535
Prefer Currency over Double in this case, to avoid floating-point issues.
I have this code which shifts the alphabet by a certain amount. The size of the alphabet is 26. When I enter a larger size shift (for example 22) I get some weird characters displaying. I think I need to mod the ASCII alphabet to 26 to get it working but Im not quite sure which bit to mod.
Basically I need to wrap around the alphabet (once it reaches Z it goes back to letter A) Do I have to create a dictionary for the mod to work (like A = 0... Z = 26) or can I stick with using the normal ASCII table? Here is the code below:
Public Function encrypt(ByVal input As String) 'input is a variable within the funcion
Dim n as Integer
Dim i As Integer
n = key.Text Mod 26 'gets what is in the text box of 'key' and sets it as n
' the key is a multiple of 26 so 26 will = 0
'need to remove white spaces
While input.Contains(" ") 'when the input text contains a space
input = input.Replace(" ", "") 'replaces it with no space.
End While
For i = 1 To Len(input) 'find the length of the input
Mid(input, i, 1) = Chr(Asc(Mid(input, i, 1)) + n) 'chr returns the character associated with the specified character code
'
Next
encrypt = input
End Function
Look at this code:
For i = 1 To Len(input) 'find the length of the input
Mid(input, i, 1) = Chr(Asc(Mid(input, i, 1)) + n) 'chr returns the character associated with the specified character code
'
Next
String indexes are 0-based. Your first index is 0, not 1! Also, you are assigning to the result of a function call. You need to instead construct a new string.
You didn't say, but the way you used the Replace and Contains methods indicates .Net, and if that's the case, I would do it like this:
Public Function encrypt(ByVal key As Integer, ByVal input As String) As String 'Don't forget the return type on the function
key = key Mod 26
Return New String(input.Replace(" ", "").ToUpper().Select(Function(c) Chr(((Asc(c) + key - Asc("A"c)) Mod 26) + Asc("A"c))).ToArray())
End Function
Just like that, and it's almost a one-liner. I can see this works now by calling it this way:
Encrypt("C"c, "the quick brown fox jumps over the lazy dog")
Encrypt("D"c, "the quick brown fox jumps over the lazy dog")
The results:
BPMYCQKSJZWEVNWFRCUXMLWDMZBPMTIHGLWOA
CQNZDRLTKAXFWOXGSDVYNMXENACQNUJIHMXPB
Look for the results mapped for the word "lazy", and you will see that the 'a' wraps to 'z' and 'y' correctly, and that the 'D' key results are one letter off of the 'C' results.