I have a folder ~/ConfigurationDirectory. The sub-folders within this folder are named as follows
5.0.0.1
5.0.0.2
5.0.0.3
...
Now, the requirement is that - Identify the folder which has the "largest" name numerically and create a copy of the folder. Rename the new folder as 5.0.0.n+1 (assuming that the largest numerically available folder is 5.0.0.n)
I have written code which will identify the largest named folder. Also, I have written the code which will do the copy of folder and sub-folders. What I am not able to get is, how do I get the name of the new folder, i.e., 5.0.0.n+1
How do I do this in C#? Any pointers would suffice rather than complete coding.
Thanks!
Assuming the numbers you're working with are not simple four-part version numbers, you're going to want to use the string.Split() to break up the folder name, and then Convert.ToInt32() or int.Parse() to turn the last chunk into a number. From there, you increment it, and then use something like string.Format() to turn it back into a folder name.
If, however, you are indeed working with simple version numbers, then using the System.Version class (specifically, the Parse() or TryParse() and ToString() methods) would be a significantly more straightforward implementation.
This is the most correct solution, imo:
Version version;
if (Version.TryParse("5.0.0.0", out version))
{
// your logic here
return new Version(
version.Major,
version.Minor,
version.Build,
version.Revision + 1).ToString();
// will return 5.0.0.1
}
else
{
// error handling here
}
You can use string.LastIndexOf for this purpose (this is much more light-weight than using string.Split):
static string GetNextFolderName(string folderName)
{
int lastDotPosition = folderName.LastIndexOf('.');
string lastPartOfFolderName = folderName.Substring(lastDotPosition + 1);
int number;
if (int.TryParse(lastPartOfFolderName, out number))
{
number++;
return folderName.Substring(0, lastDotPosition + 1) + number.ToString();
}
else
{
// You've got a problem on your hands, here.
throw new FormatException();
}
}
UPDATE: It has been pointed out that this approach is perhaps excessive in light of the existence of Version.TryParse. A few points in response to that:
Version.TryParse is available as of .NET 4.0. Many developers are not using .NET 4.0; therefore to discard any alternative approach right out is (in my opinion) quite narrow-sighted.
It has not been indicated whether performance is much of a concern. Presumably, it is not. However, when you think about the problem conceptually, Version.TryParse is actually doing significantly more work than we need in this case: it is looking at every individual component of the version string and parsing them all into a complete Version object. The approach outlined above, on the other hand, only bothers to examine the last part of the version string, and is therefore more efficient. I have verified this: using the approach above executes in about 30% of the time it takes using Version.TryParse.
Of course it is fair to point out that, if one already knew of Version.TryParse and chose to write the above code anyway, one would be guilty of premature optimization. That said, suppose you did not know about it, and you already wrote the above code. Would the right thing to do be to refactor the code to use Version.TryParse, keeping the same functionality and slowing performance by about 200%? I'm not asking rhetorically; perhaps in some cases, for the sake of simplicity and maintainability, it might be. But it would be a judgment call.
I post these points primarily as a rebuttal to anyone who would immediately dismiss a solution simply because it performs the same task as an "out-of-the-box" solution. Sometimes, depending on your circumstances, it can make sense to do something yourself anyway. Just know what you're getting yourself into, and be ready to take a step back and change direction if and when it becomes appropriate to do so.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
static class Extensions
{
public static TOutput[] ToArray<TSource, TOutput>(this IEnumerable<TSource> col, Converter<TSource, TOutput> converter)
{
return Array.ConvertAll<TSource, TOutput>(col.ToArray(), converter);
}
}
class Program
{
static void Main(string[] args)
{
string original = "5.0.0.0";
int[] tmp = original.Split('.').ToArray<string, int>(new Converter<string, int>(delegate(string s)
{
int result;
return int.TryParse(s, out result) ? result : 0;
}));
tmp[tmp.Length - 1]++;
// re should contain 5.0.0.1
string re = String.Join(".", tmp);
}
}
}
It's a simple algorithm, which can be applied to any number of elements:
Split the string on the dots. Call the resulting array a.
Convert the last element of a to an integer. Call this integer i.
i++
a[last] = i.ToString()
Join the elements of a using a dot as the separator.
Make sure that your identification algorithm really does select the numerically largest value: if you have 5.0.0.9 and 5.0.0.10, then you would find 5.0.0.9 if the identification really uses alphabetic ordering.
Related
Hoping someone can help. I'm a very basic beginner in C#. I set myself the task of creating a console application where I enter a resource I need i.e Screw or screws into the console, hit enter and it retrieves all the junk from the list that contain that word, along with the amount of resources you would receive from the junk. So Type Writer would be 2 screws. It's for Fallout 76 so I can see what junk contains what resource.
However I'm having a few issues:
The console only returns one result for screw, even though there are multiple results. (How do I resolve this and receive multiple results? i.e Clip board and Toy Car)
How do I search and get results for partial matches i.e if I type scre or screws?
Is there a better way of creating a console application where you store values and a user searches for those values? I cannot find anything close to what I need scouring the internet.
Thank you for all the help.
using System;
using System.Collections.Generic;
class JunkList
{
public string Resource { get; set; }
public string Junk { get; set; }
public int Amount { get; set; }
public JunkList(string r, string j, int a)
{
this.Resource = r;
this.Junk = j;
this.Amount = a;
}
}
class Program
{
static void Main(string[] args)
{
string searchName;
List<JunkList> infoList = new List<JunkList>();
infoList.Add(new JunkList("Screw", "Type Writer", 2));
infoList.Add(new JunkList("Screw", "Clip Board", 1));
infoList.Add(new JunkList("Screw", "Toy Car", 3));
Console.Write("Which resource do you want to search for?? \n");
searchName = Console.ReadLine();
for (int i = 0; i < infoList.Count; i++)
{
if (string.Compare(searchName, infoList[i].Resource, true) == 0)
{
Console.Write("Resource : " + infoList[i].Resource + "\n");
Console.Write("Junk : " + infoList[i].Junk + "\n");
Console.Write("Resource Amount : " + infoList[i].Amount + "\n");
break;
}
}
Console.ReadKey();
}
}
The console only returns one result for screw, even though there are
multiple results. (How do I resolve this and receive multiple results?
i.e Clip board and Toy Car)
Your issue is that you're breaking after finding the very first result:
if (string.Compare(searchName, infoList[i].Resource, true) == 0)
{
Console.Write("Resource : " + infoList[i].Resource + "\n");
Console.Write("Junk : " + infoList[i].Junk + "\n");
Console.Write("Resource Amount : " + infoList[i].Amount + "\n");
break; // REMOVE THIS LINE
}
break means that you're exiting from your for loop, so you're actually exiting as soon as you find a result.
How do I search and get results for partial matches i.e if I type scre
or screws?
You can change your if condition from
if (string.Compare(searchName, infoList[i].Resource, true) == 0)
to something like
if (infoList[i].Resource.ToLowerInvariant().Contains(searchName.ToLowerInvariant()))
This checks if the inserted string is contained in one of the strings that you have in your list. The ToLowerInvariant is used to make the search case-insensitive.
Of course, this is not a fuzzy-search, so searching for screws won't lead to any result. Doing fuzzy searches is a little bit more complex and it's probably outside the scope of this question.
Is there a better way of creating a console application where you
store values and a user searches for those values? I cannot find
anything close to what I need scouring the internet.
Opinion-based questions are not meant for StackOverflow, and asking a better way to do something is one of those. I don't think you'll get an answer on this.
To make it a less subjective, I'm going to interpret your last question as "Is there a common software pattern or approach that is used for storing data objects that can then be easily searched?"
In that regard, you're describing features and capabilities that a database is really good at, specifically storing some table of data and providing a fast way to search (query) it using criteria that you define.
C# and the .NET frameworks offer some pretty in-depth and robust tools for leveraging databases and managing mappings between data classes like JunkList and database tables; these types of tools are called ORMs, or Object Relational Mappers, and you'll see reference to them scattered throughout Microsoft's documentation, especially Entity Framework.
When getting started, more complicated ORMs can get a bit overwhelming, so it's not a bad idea to start small. Check out some very simple ORMs that use something like SQLite, which just live in a file and require minimal dependencies (the act of calling the database actually can be enough to create it!).
You might take a look at https://github.com/praeclarum/sqlite-net , which is very easy to set up in a matter of minutes and start using with just the basics provided in its documentation.
The reason you only get one result back is because of the break statement. It cancels the for loop. Try removing it.
Try looking at the String.Contains() method.
I'm working hard on my new project, I'm totally new in C# so I don't really understand much, and I'm making a loading screen now, and do you know that "Loading message".
So I would like to make a few lines, and the code should be able to pick a random line and display when it is loading. Like this example:
var randomLoadingMessage = function() {
var lines = new Array(
"Locating the required gigapixels to render...",
"Spinning up the hamster...",
"Shovelling coal into the server...",
"Programming the flux capacitor"
);
return lines[Math.round(Math.random()*(lines.length-1))];
}
I found it on the internet. How could I use it on c#?
I need help to do something similar in c#
Here are the pieces you need to solve this
A Program. Below is the boilerplate code for a C# console application. Why's this needed? So your line of code has some context to run in. NB: You could run code via LinqPad without this, or you could use a different type of project to host your code; but for now I'm keeping things simple.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
}
}
An array holding the strings you want to display. See Options for initializing a string array for additional info / options:
string[] lines = new [] {
"Locating the required gigapixels to render...",
"Spinning up the hamster...",
"Shovelling coal into the server...",
"Programming the flux capacitor"
);
A way to pick one of these strings at random. You get a string from the array by putting a number (the index) in square brackets after the variable name, with each item in the array having consecutive numbers starting at 0. ; e.g. lines[1] would give you the string "Spinning up the hamster...". You can get a random number using an instance Random class's Next method. This method requires you to provide parameters to define the range in which the result should fall. The method returns a double but you need an int for your index, so you'll have to convert the result. See How do I generate a random int number in C#? for more.
int randomIndex = myRandom.Next(0, lines.Length);
For now I'll leave it there or I'd be giving you the full solution. If you have issues though, please post new questions here with what you've tried so far, and why it's not working (i.e. are you getting an error message, if so what, or is it doing something different to what you'd expect).
I recently came across a php code where a CSV string was split into two variables:
list($this->field_one, $this->field_two) = explode(",", $fields);
I turned this into:
string[] tmp = s_fields.Split(',');
field_one = tmp[0];
field_two = tmp[1];
Is there a C# equivalent without creating a temporary array?
Jon Skeet said the right thing. GC will do the thing, don't you worry.
But if you like the syntax so much (which is pretty considerable), you can use this, I guess.
public static class MyPhpStyleExtension
{
public void SplitInTwo(this string str, char splitBy, out string first, out string second)
{
var tempArray = str.Split(splitBy);
if (tempArray.length != 2) {
throw new NotSoPhpResultAsIExpectedException(tempArray.length);
}
first = tempArray[0];
second = tempArray[1];
}
}
I almost feel guilty by writing this code. Hope this will do the thing.
The answer to your quite narrow question is no. C# does not provide a 'multi-assignment' capability, so you cannot extract an arbitrary set of values from anything (such as Split()) and break them out into individual named variables.
There is a workaround for a specific number of variables, by writing a parameter with out arguments. See #vlad for an answer based on that.
But why would you want to? C# provides an impressive range of features that will allow you to take apart strings and deal them with the parts in a such a wide range of different ways that the lack of 'multi-assignment' should barely be noticed.
Parsing strings usually involves other operations such as dealing with formatting errors, trimming white space, case folding. There could be less than 2 strings, or more. Requirements could change over time. When you are ready for a more capable string parser, C# will be waiting.
You may use the following approach:
-Create a class that inherits from dynamic object.
-Create a local dictionary that will store your variables values in the inherited class.
-Override the TryGetMember and TrySetMember functions to get and set values from and into the dictionary.
-Now, you can split your string and put it in the dictionary, then access your variable like:
dynamicObject.var1
Is there a C# library that provides the functionality of ">>" and "<<" for IO in C++? It was really convenient for console apps. Granted not a lot of console apps are in C#, but some of us use it for them.
I know about Console.Read[Line]|Write[Line] and Streams|FileStream|StreamReader|StreamWriter thats not part of the question.
I dont think im specific enough
int a,b;
cin >> a >> b;
IS AMAZING!!
string input = Console.ReadLine();
string[] data = input.split( ' ' );
a = Convert.ToInt32( data[0] );
b = Convert.ToInt32( data[1] );
... long winded enough? Plus there are other reasons why the C# solution is worse. I must get the entire line or make my own buffer for it. If the line im working on is IDK say the 1000 line of Bells Triangle, I waste so much time reading everything at one time.
EDIT:
GAR!!!
OK THE PROBLEM!!!
Using IntX to do HUGE number like the .net 4.0 BigInteger to produce the bell triangle. If you know the bell triangle it gets freaking huge very very quickly. The whole point of this question is that I need to deal with each number individually. If you read an entire line, you could easily hit Gigs of data. This is kinda the same as digits of Pi. For Example 42pow1048576 is 1.6 MB! I don't have time nor memory to read all the numbers as one string then pick the one I want
No, and I wouldn't. C# != C++
You should try your best to stick with the language convention of whatever language you are working in.
I think I get what you are after: simple, default formatted input. I think the reason there is no TextReader.ReadXXX() is that this is parsing, and parsing is hard: for example: should ReadFloat():
ignore leading whitespace
require decimal point
require trailing whitespace (123abc)
handle exponentials (12.3a3 parses differently to 12.4e5?)
Not to mention what the heck does ReadString() do? From C++, you would expect "read to the next whitespace", but the name doesn't say that.
Now all of these have good sensible answers, and I agree C# (or rather, the BCL) should provide them, but I can certainly understand why they would choose to not provide fragile, nearly impossible to use correctly, functions right there on a central class.
EDIT:
For the buffering problem, an ugly solution is:
static class TextReaderEx {
static public string ReadWord(this TextReader reader) {
int c;
// Skip leading whitespace
while (-1 != (c = reader.Peek()) && char.IsWhiteSpace((char)c)) reader.Read();
// Read to next whitespace
var result = new StringBuilder();
while (-1 != (c = reader.Peek()) && !char.IsWhiteSpace((char)c)) {
reader.Read();
result.Append((char)c);
}
return result.ToString();
}
}
...
int.Parse(Console.In.ReadWord())
Nope. You're stuck with Console.WriteLine. You could create a wrapper that offered this functionality, though.
You can Use Console.WriteLine , Console.ReadLine ..For the purpose.Both are in System NameSpace.
You have System.IO.Stream(Reader|Writer)
And for console: Console.Write, Console.Read
Not that I know of. If you are interested of the chaining outputs you can use System.Text.StringBuilder.
http://msdn.microsoft.com/en-us/library/system.text.stringbuilder(VS.71).aspx
StringBuilder builder = new StringBuilder();
builder.Append("hello").Append(" world!");
Console.WriteLine(builder.ToString());
Perhaps not as pretty as C++, but as another poster states, C# != C++.
This is not even possible in C#, no matter how hard you try:
The left hand side and right hand side of operators is always passed by value; this rules out the possibility of cin.
The right hand side of << and >> must be an integer; this rules out cout.
The first point is to make sure operator overloading is a little less messy than in C++ (debatable, but it surely makes things a lot simpler), and the second point was specifically chosen to rule out C++'s cin and cout way of dealing with IO, IIRC.
I'm trying to work through the problems on projecteuler.net but I keep running into a couple of problems.
The first is a question of storing large quanities of elements in a List<t>. I keep getting OutOfMemoryException's when storing large quantities in the list.
Now I admit I might not be doing these things in the best way but, is there some way of defining how much memory the app can consume?
It usually crashes when I get abour 100,000,000 elements :S
Secondly, some of the questions require the addition of massive numbers. I use ulong data type where I think the number is going to get super big, but I still manage to wrap past the largest supported int and get into negative numbers.
Do you have any tips for working with incredibly large numbers?
Consider System.Numerics.BigInteger.
You need to use a large number class that uses some basic math principals to split these operations up. This implementation of a C# BigInteger library on CodePoject seems to be the most promising. The article has some good explanations of how operations with massive numbers work, as well.
Also see:
Big integers in C#
As far as Project Euler goes, you might be barking up the wrong tree if you are hitting OutOfMemory exceptions. From their website:
Each problem has been designed according to a "one-minute rule", which means that although it may take several hours to design a successful algorithm with more difficult problems, an efficient implementation will allow a solution to be obtained on a modestly powered computer in less than one minute.
As user Jakers said, if you're using Big Numbers, probably you're doing it wrong.
Of the ProjectEuler problems I've done, none have required big-number math so far.
Its more about finding the proper algorithm to avoid big-numbers.
Want hints? Post here, and we might have an interesting Euler-thread started.
I assume this is C#? F# has built in ways of handling both these problems (BigInt type and lazy sequences).
You can use both F# techniques from C#, if you like. The BigInt type is reasonably usable from other languages if you add a reference to the core F# assembly.
Lazy sequences are basically just syntax friendly enumerators. Putting 100,000,000 elements in a list isn't a great plan, so you should rethink your solutions to get around that. If you don't need to keep information around, throw it away! If it's cheaper to recompute it than store it, throw it away!
See the answers in this thread. You probably need to use one of the third-party big integer libraries/classes available or wait for C# 4.0 which will include a native BigInteger datatype.
As far as defining how much memory an app will use, you can check the available memory before performing an operation by using the MemoryFailPoint class.
This allows you to preallocate memory before doing the operation, so you can check if an operation will fail before running it.
string Add(string s1, string s2)
{
bool carry = false;
string result = string.Empty;
if (s1.Length < s2.Length)
s1 = s1.PadLeft(s2.Length, '0');
if(s2.Length < s1.Length)
s2 = s2.PadLeft(s1.Length, '0');
for(int i = s1.Length-1; i >= 0; i--)
{
var augend = Convert.ToInt64(s1.Substring(i,1));
var addend = Convert.ToInt64(s2.Substring(i,1));
var sum = augend + addend;
sum += (carry ? 1 : 0);
carry = false;
if(sum > 9)
{
carry = true;
sum -= 10;
}
result = sum.ToString() + result;
}
if(carry)
{
result = "1" + result;
}
return result;
}
I am not sure if it is a good way of handling it, but I use the following in my project.
I have a "double theRelevantNumber" variable and an "int PowerOfTen" for each item and in my relevant class I have a "int relevantDecimals" variable.
So... when large numbers is encountered they are handled like this:
First they are changed to x,yyy form. So if the number 123456,789 was inputed and the "powerOfTen" was 10, it would start like this:
theRelevantNumber = 123456,789
PowerOfTen = 10
The number was then: 123456,789*10^10
It is then changed to:
1,23456789*10^15
It is then rounded by the number of relevant decimals (for example 5) to 1,23456 and then saved along with "PowerOfTen = 15"
When adding or subracting numbers together, any number outside the relevant decimals are ignored. Meaning if you take:
1*10^15 + 1*10^10 it will change to 1,00001 if "relevantDecimals" is 5 but will not change at all if "relevantDecimals" are 4.
This method make you able to deal with numbers up doubleLimit*10^intLimit without any problem, and at least for OOP it is not that hard to keep track of.
You don't need to use BigInteger. You can do this even with string array of numbers.
class Solution
{
static void Main(String[] args)
{
int n = 5;
string[] unsorted = new string[6] { "3141592653589793238","1", "3", "5737362592653589793238", "3", "5" };
string[] result = SortStrings(n, unsorted);
foreach (string s in result)
Console.WriteLine(s);
Console.ReadLine();
}
static string[] SortStrings(int size, string[] arr)
{
Array.Sort(arr, (left, right) =>
{
if (left.Length != right.Length)
return left.Length - right.Length;
return left.CompareTo(right);
});
return arr;
}
}
If you want to work with incredibly large numbers look here...
MIKI Calculator
I am not a professional programmer i write for myself, sometimes, so sorry for unprofessional use of c# but the program works. I will be grateful for any advice and correction.
I use this calculator to generate 32-character passwords from numbers that are around 58 digits long.
Since the program adds numbers in the string format, you can perform calculations on numbers with the maximum length of the string variable. The program uses long lists for the calculation, so it is possible to calculate on larger numbers, possibly 18x the maximum capacity of the list.